高精度加法、乘法详解
一、为什么需要高精度运算
由于现有数据类型如int,longlong不足以存储我们需要的很大的数,如几亿、几十亿,因此我们需要使用数组来存储数据。
二、高精度加法
- 我们使用string类型来存储数据,c语言我们可以使用数组存储。
- 为便于运算我们在数位较小的数前面补’0’。
- 代码:
string add(string a, string b) { if (a.size() < b.size()) // 这里通过判断,保证是大数加小数 return add(b, a); memset(q, 0, sizeof(q)); // 每次运算将数组清零 string c; for (int i = b.size(); i < a.size(); i ++) b = '0' + b; // 在“小数”前面补零 for (int i = b.size() - 1; i >= 0; i --) {// 从最后一位开始运算 // 因为加法结果可能会比大数多一位,因此q从i+1开始存储 q[i + 1] += (a[i] - '0') + (b[i] - '0'); if (q[i + 1] >= 10) { q[i + 1] %= 10; q[i] ++; // 大于10则进位 } } if (q[0] != 0) // 第一位不为0 c = q[0] + '0'; for (int i = 1; i <= b.size(); i ++) // 将结果存入字符串 c += q[i] + '0'; return c; }
三、高精度乘法
-
在进行高精度乘法时我们是将第一个数的每一位与第二一个数分别相乘然后相加,我们需要注意第一个数的每一位对应的值。
-
代码:
string mul(string a, string b) { if (a.size() < b.size()) return mul(b, a); if (a == "0" or b == "0") // 当其中一个数为0时,我们返回0 return "0"; memset(q, 0, sizeof(q)); string c; string temp; for (int i = b.size() - 1; i >= 0; i --) { temp = ""; // 倍数 int te = b[i] - '0'; int t = 0; int cf = 0; // 进位 if (te != '0') { for (int j = 0; j < b.size() - 1 - i; j ++) temp += '0'; // 表示乘的数是个位、十位还是百位···因此在后面补零 for (int j = a.size() - 1; j >= 0; j --) { t = ((a[j] - '0') * te + cf) % 10; cf = ((a[j] - '0') * te + cf) / 10; // 满10进位 temp = char(t + '0') + temp; // 每次乘得的数放在前面 } if (cf != 0) temp = char(cf + '0') + temp; } c = add(c, temp); // 将每次相乘的结果相加 } return c; }
四、示例
-
示例代码:
#include <iostream> #include <cstring> using namespace std; const int N = 1e5 + 10; int q[N]; // 通过q进行计算 string add(string a, string b) { if (a.size() < b.size()) return add(b, a); memset(q, 0, sizeof(q)); string c; for (int i = b.size(); i < a.size(); i ++) b = '0' + b; for (int i = b.size() - 1; i >= 0; i --) { q[i + 1] += (a[i] - '0') + (b[i] - '0'); if (q[i + 1] >= 10) { q[i + 1] %= 10; q[i] ++; } } if (q[0] != 0) c = q[0] + '0'; for (int i = 1; i <= b.size(); i ++) c += q[i] + '0'; return c; } string mul(string a, string b) { if (a.size() < b.size()) return mul(b, a); if (a == "0" or b == "0") return "0"; memset(q, 0, sizeof(q)); string c; string temp; for (int i = b.size() - 1; i >= 0; i --) { temp = ""; // 倍数 int te = b[i] - '0'; int t = 0; int cf = 0; // 进位 if (te != '0') { for (int j = 0; j < b.size() - 1 - i; j ++) temp += '0'; // 表示乘的是个位、十位还是百位··· for (int j = a.size() - 1; j >= 0; j --) { t = ((a[j] - '0') * te + cf) % 10; cf = ((a[j] - '0') * te + cf) / 10; temp = char(t + '0') + temp; } if (cf != 0) temp = char(cf + '0') + temp; } c = add(c, temp); // 将每次结果相加 } return c; } int main(void) { string a, b, c = "0"; while (cin >> a >> b) { c = add(a, b); cout << c; } system("pause"); return 0; }