主程序讀入兩個**字符串**形式的大數(含小數點),通過函數實現高精度減法,輸出結果字符串。需處理:符號判斷、小數點對齊、逐位減法借位、前導零處理、負號輸出。
s1, s2,記錄小數點位置 pos1, pos2,去除小數點得到純數字串 d1, d2。big - small 並記錄結果符號。res[i] = big[i] - small[i] - borrow;若 res[i] < 0 則 res[i] += 10; borrow = 1 否則 borrow = 0。
#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.89 | 55.56 | 正常減法 |
| 100.0 99.999 | 0.001 | 借位跨越小數點 |
| 0.001 0.002 | -0.001 | 結果為負 |
| 123 45.6 | 77.4 | 整數減小數 |
| 100000...(500位) 1 | 999...999 | 超長整數 |
核心技巧:**字符串反轉→低位對齊→逐位借位→反轉回→格式化**,可處理任意長度高精度加減乘除,是大數運算基礎模板。