高精度计算
一、为什么需要高精度计算?
- 常见数据类型及其范围
| 数据类型 | 存储大小 | 数值范围 |
|---|---|---|
| short | 2 Byte | -32,768 ~ 32,767 (-2¹⁵ ~ 2¹⁵-1) |
| int | 4 Byte | -2,147,483,648 ~ 2,147,483,647 (-2³¹ ~ 2³¹-1) |
| long long | 8 Byte | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 (-2⁶³ ~ 2⁶³-1) |
| float | 4 Byte | ≈ -10³⁸ ~ 10³⁸ (精度约6-7位小数) |
| double | 8 Byte | ≈ -10³⁰⁸ ~ 10³⁰⁸ (精度约15-16位小数) |
| char | 1 Byte | -128 ~ 127 |
- 高精度计算定义
当参与运算的数值范围超出标准数据类型的表示能力时,需要使用特殊方法进行运算,这就是高精度计算。
想象你要计算:
12345678901234567890 + 98765432109876543210
这个数字太大了,连long long(能存19位数字)都存不下,这时候就需要高精度计算。
二、高精度计算的基本思路
就像我们小学学的竖式计算一样:
-
用字符串存大数:因为字符串可以存很长的数字
- 例如:"12345678901234567890"
-
倒着存储数字:方便计算时对齐个位
- "12345" → 存成[5,4,3,2,1]
-
逐位计算:像列竖式一样一位一位算
-
结果再倒回来:把结果再倒过来变成正常顺序
三、四则运算的简单思路
加法
- 对齐位数
- 逐位相加
- 处理进位
#include <bits/stdc++.h>
using namespace std;
int a[300], b[300], c[500], len;
string s1, s2;
int main(){
cin >> s1 >> s2;
for(int i = 0; i < s1.size(); i++)
a[s1.size() - i - 1] = s1[i] - '0';
for(int i = 0; i < s2.size(); i++)
b[s2.size() - i - 1] = s2[i] - '0';
if(s1.size() > s2.size())
len = s1.size();
else
len = s2.size();
for(int i = 0; i < len; i++)
c[i] = a[i] + b[i];
for(int i = 0; i < len; i++)
if(c[i] >= 10){
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
if(c[len] != 0)
len++;
for(int i = len - 1; i >= 0; i--)
printf("%d", c[i]);
return 0;
}
减法
- 比较大小确定符号
- 大数减小数
- 处理借位
#include <bits/stdc++.h>
using namespace std;
int a[300], b[300], c[300], len, p;
string s1, s2;
int main(){
cin >> s1 >> s2;
if((s1.size() < s2.size())||((s1.size() == s2.size())&&(s1 < s2))){
printf("-");
swap(s1, s2);
}
for(int i = 0; i < s1.size(); i++)
a[s1.size() - i - 1] = s1[i] - '0';
for(int i = 0; i < s2.size(); i++)
b[s2.size() - i - 1] = s2[i] - '0';
len = s1.size();
for(int i = 0; i < len; i++){
if(a[i] < b[i]){
a[i + 1]--;
a[i] += 10;
}
c[i] = a[i] - b[i];
}
for(int i = len - 1; i >= 0; i--)
if(c[i] != 0){
p = i;
break;
}
for(int i = p; i >= 0; i--)
printf("%d", c[i]);
return 0;
}
乘法
- 双重循环逐位相乘
- 累加部分积
- 处理进位
#include <bits/stdc++.h>
using namespace std;
int a[300], b[300], c[500], p;
string s1, s2;
int main() {
cin >> s1 >> s2;
for(int i = 0; i < s1.size(); i++)
a[s1.size() - i - 1] = s1[i] - '0';
for(int i = 0; i < s2.size(); i++)
b[s2.size() - i - 1] = s2[i] - '0';
for(int i = 0; i < s1.size(); i++)
for(int j = 0; j < s2.size(); j++){
c[i + j] += a[i] * b[j];
if(c[i + j] >= 10){
c[i + j + 1] += c[i + j] / 10;
c[i + j] %= 10;
}
}
for(int i = s1.size() + s2.size() - 1; i >= 0; i--)
if(c[i] != 0){
p = i;
break;
}
for(int i = p; i >= 0; i--)
printf("%d", c[i]);
return 0;
}
除法
#include <bits/stdc++.h>
using namespace std;
int a, b, n, r;
int main(){
scanf("%d%d%d", &a, &b, &n);
printf("%d.", a / b);
r = a % b;
for(int i = 1; i <= n; i++){
r *= 10;
printf("%d", r / b);
r %= b;
}
return 0;
}

浙公网安备 33010602011771号