高精度加法和乘法
加法(只支持自然数的大整数相加)
1.通过模拟加法算式,从右往左依次累加,如果两个不一样长,要在短的前面用0补上。
2.取余保留,除10进位,注意最后一位如果有进位要把进位加上去。
乘法(只支持自然数的大整数相乘)
1. 通过模拟乘法算式,从右往左数的话,s1[i] * s2[j] 贡献给了ans[i+j]。
2.所以为了方便从右往左数, 先把s1,s2翻转,且乘法后的结果最多有 len1+len2位。
3.因为s1[i] * s2[j] 和s1[j] * s2[i]都会贡献给ans[i+j],所以要写两层for循环。
4.贡献值 = 第一次贡献值 + 第二次贡献值,然后取余保留,除10进位。
5.最后得到结果,要找到非0的首位,并且要反过来,也要判断结果为0的时候,返回"0"。
string add(string s1, string s2) {//模拟加法算式,从右往左加(只支持自然数相加)
int len1 = s1.length(), len2 = s2.length();
if (len1 < len2) {//位数不够用0补
string t(len2 - len1, '0');
s1 = t + s1;
} else if (len2 < len1) {
string t(len1 - len2, '0');
s2 = t + s2;
}
string ans = s1;
int car = 0;
for (int i = s1.length() - 1; i >= 0; i--) {
ans[i] = (s1[i] - '0' + s2[i] - '0' + car) % 10 + '0';
car = (s1[i] - '0' + s2[i] - '0' + car) / 10;
}
if (car) ans = (char) (car + '0') + ans;//多出一位进位要加上
return ans;
}
string mul(string s1, string s2) {//(只支持自然数相乘)
vector<int> v(s1.length() + s2.length(), 0);
reverse(s1.begin(), s1.end());//翻转便于计算,反转后从右往左,依次为个位、十位...
reverse(s2.begin(), s2.end());
for (int i = 0; i < s1.length(); i++) {
for (int j = 0; j < s2.length(); j++) {
int t = (s1[i] - '0') * (s2[j] - '0') + v[i + j];//
v[i + j] = t % 10;//取余保留
v[i + j + 1] += t / 10;//除10进位
}
}
int i;
for (i = v.size() - 1; v[i] == 0; i--);//取非0首位作为第一位
string ans(i + 1, '0');
for (int j = 0; j <= i; j++)//把结果再次反过来保存即可
ans[j] = v[i - j] + '0';
if (ans == "") ans = "0";//如果不存在非0首位,则答案为 "0"
return ans;
}