首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 高精度小數減法:大數字符串對齊、借位、輸出完整實現

     編輯:程式設計疑難解答

題目要求

主程序讀入兩個**字符串**形式的大數(含小數點),通過函數實現高精度減法,輸出結果字符串。需處理:符號判斷、小數點對齊、逐位減法借位、前導零處理、負號輸出。

核心算法流程

  1. 輸入預處理:讀取字符串 s1, s2,記錄小數點位置 pos1, pos2,去除小數點得到純數字串 d1, d2。
  2. 小數點對齊:在較短小數部分右側補 0,使兩數小數位數一致;整數部分左側補 0 對齊最高位。
  3. 大小比較:從最高位逐位比較,決定 big - small 並記錄結果符號。
  4. 逐位減法(從低位向高位):res[i] = big[i] - small[i] - borrow;若 res[i] < 0 則 res[i] += 10; borrow = 1 否則 borrow = 0。
  5. 結果格式化:插入小數點、去除前導零(保留至少一位)、去除尾部多餘零(小數部分)、添加負號。

完整可編譯代碼 (C++11)


#include <bits/stdc++.h>
using namespace std;

string subtractStrings(string a, string b) { // a >= b, 純整數串,高位在前
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
    string res;
    int borrow = 0;
    for (size_t i = 0; i < a.size(); ++i) {
        int da = a[i] - '0';
        int db = i < b.size() ? b[i] - '0' : 0;
        int diff = da - db - borrow;
        if (diff < 0) { diff += 10; borrow = 1; } else borrow = 0;
        res.push_back('0' + diff);
    }
    while (res.size() > 1 && res.back() == '0') res.pop_back();
    reverse(res.begin(), res.end());
    return res;
}

string highPrecisionSub(string s1, string s2) {
    // 1. 符號處理:這裡假設輸入非負,負數情況可擴展
    // 2. 分離整數/小數部分
    auto split = [](const string& s) -> pair {
        size_t p = s.find('.');
        if (p == string::npos) return {s, ""};
        return {s.substr(0, p), s.substr(p + 1)};
    };
    auto [int1, dec1] = split(s1);
    auto [int2, dec2] = split(s2);

    // 3. 小數部分右對齊補0
    int maxDec = max(dec1.size(), dec2.size());
    dec1.append(maxDec - dec1.size(), '0');
    dec2.append(maxDec - dec2.size(), '0');

    // 4. 整數部分左對齊補0
    int maxInt = max(int1.size(), int2.size());
    int1 = string(maxInt - int1.size(), '0') + int1;
    int2 = string(maxInt - int2.size(), '0') + int2;

    // 5. 合併為純整數串比較大小
    string num1 = int1 + dec1, num2 = int2 + dec2;
    bool negative = false;
    if (num1 < num2) { swap(num1, num2); negative = true; }

    // 6. 高精度減法
    string intRes = subtractStrings(num1, num2);

    // 7. 插入小數點
    if (maxDec > 0) {
        if (intRes.size() <= maxDec) intRes = string(maxDec - intRes.size() + 1, '0') + intRes;
        intRes.insert(intRes.size() - maxDec, ".");
    }

    // 8. 格式化:去首尾多餘0
    // 去整數部分前導0
    size_t dotPos = intRes.find('.');
    string intPart = (dotPos == string::npos) ? intRes : intRes.substr(0, dotPos);
    string decPart = (dotPos == string::npos) ? "" : intRes.substr(dotPos + 1);
    intPart.erase(0, min(intPart.find_first_not_of('0'), intPart.size() - 1));
    // 去小數部分尾部0
    decPart.erase(decPart.find_last_not_of('0') + 1);
    string finalRes = intPart + (decPart.empty() ? "" : "." + decPart);
    if (finalRes.empty() || finalRes == ".") finalRes = "0";

    return (negative ? "-" : "") + finalRes;
}

int main() {
    string s1, s2;
    cout << "輸入兩個大數(可含小數點),空格分隔:\n";
    cin >> s1 >> s2;
    cout << "結果:" << highPrecisionSub(s1, s2) << endl;
    return 0;
}

關鍵測試用例

輸入輸出說明
123.45 67.8955.56正常減法
100.0 99.9990.001借位跨越小數點
0.001 0.002-0.001結果為負
123 45.677.4整數減小數
100000...(500位) 1999...999超長整數

核心技巧:**字符串反轉→低位對齊→逐位借位→反轉回→格式化**,可處理任意長度高精度加減乘除,是大數運算基礎模板。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved