高精度
当数据的数值特别大时,各种类型都存不下的时候,就要用高精度算法来计算加减乘除
- 高精度是算法中处理超出常规数据类型表示范围数值的计算方式。
- 其核心是用数组、字符串等结构存储大数值,模拟手工运算逻辑。
- 涵盖高精度加减乘除及与普通数值的混合运算,需重点处理进位与借位。
- 常采用逆序存储(低位在前)方便逐位计算,提升操作效率。
- 适用于极大整数、高精密小数场景,确保计算结果准确无溢出。
1.1高精度加法
链接: link
解法
模拟列竖式计算两数相加的过程

1.用字符串读入数据;
2.将字符串的每一位拆分,逆序放在数组中;
3.模拟列竖式计算的过程
a.对应位累加
b.处理余位
c.处理余数
4.处理余数的位数
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int a[N], b[N], c[N];
int la, lb, lc;
//高精度加法的模板 c = a + b;
void add(int c[], int a[], int b[])
{
for (int i = 0; i < lc; i++)
{
c[i] += a[i] + b[i]; //对应位相加,再加上进位
c[i + 1] += c[i] / 10;// 处理进位
c[i] %= 10;//处理余数
}
if (c[lc]) lc++;//处理结果的位数
}
int main()
{
string x, y;
cin >> x >> y;
//1.拆分每一位, 逆序放在数组中
la = x.size(), lb = y.size(), lc = max(la, lb);
for (int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';
for (int i = 0; i < lb; i++) b[lb - 1 - i] = y[i] - '0';
//模拟加法的过程
add(c, a, b);
//输出结果
for (int i = lc - 1; i >= 0; i--) cout << c[i];
return 0;
}
1.2高精度减法
例题链接:链接: link
解法
模拟列竖式计算两数相减的过程

注意点:
1.可能会有负号,所以要先判断两个数的大小,字符串判断大小的方式有所不同,
a.如果位数相同,按字典序比较。
b.如果位数不等,按字符串的长度比较
2.处理前导零。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
const int N = 1e6 + 10;
int a[N], b[N], c[N];
int la, lb, lc;
//比大小
bool cmp(string x, string y)
{
//先比长度
if (x.size() != y.size()) return x.size() < y.size();
//再按字典序比较
return x < y;
}
//减法模板
void sub(int c[], int a[], int b[])
{
for (int i = 0; i < lc; i++)
{
c[i] += a[i] - b[i];//+=原因:可能从c[i]位置存有-1;
if (c[i] < 0)
{
c[i] += 10;
c[i + 1] -= 1;//借位
}
}
//处理前导零
while (lc - 1 > 0 && c[lc - 1] == 0) lc--;
}
int main()
{
string x, y;
cin >> x >> y;
if (cmp(x, y))
{
swap(x, y);
cout << "-";
}
la = x.size(); lb = y.size(); lc = max(la, lb);
for (int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';
for (int i = 0; i < lb; i++) b[lb - 1 - i] = y[i] - '0';
sub(c, a, b);
for (int i = lc - 1; i >= 0; i--) cout << c[i];
return 0;
}
1.3高精度乘法
例题链接:链接: link
解法
无进位相乘再相加
1.模拟列竖式计算两数相乘的过程,但不考虑进位,直接把乘的结果放在对应位上
2.等到对应位置乘完并且累加之后,统一处理进位

#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int a[N], b[N], c[N];
int la, lb, lc;
//高精度乘法模板
void mul(int c[], int a[], int b[])
{
for (int i = 0; i < la; i++)
{
for (int j = 0; j < lb; j++)
{
c[i + j] += a[i] * b[j];
}
}
//处理进位
for (int i = 0; i < lc; i++)
{
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
//处理前导零
while (lc - 1 > 0 && c[lc - 1] == 0) lc--;
}
int main()
{
string x, y;
cin >> x >> y;
la = x.size(); lb = y.size(); lc = la + lb;
for (int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';
for (int i = 0; i < lb; i++) b[lb - 1 - i] = y[i] - '0';
mul(c, a, b);
for (int i = lc - 1; i >= 0; i--) cout << c[i];
return 0;
}
1.4高精度除法
例题链接:链接: link
解法
模拟列竖式相除过程(这里解决的是高精度/低精度)

注意点:
定义一个指针从高位遍历被除数,用t记录被除数,除数是b;
a.更新被除数t = t* 10 + a[i];
b.t/b表示这一位的商,t%b表示这一位的余数;
c.用t记录上一次的余数,重复上面过程。
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int a[N], b, c[N];
int la, lc;
//高精度除法模板
void sub(int c[], int a[], int b)
{
LL t = 0;
for (int i = la - 1; i >= 0; i--)
{
t = t * 10 + a[i];
c[i] = t / b;
t %= b;
}
//处理前导零
while (lc - 1 > 0 && c[lc - 1] == 0) lc--;
}
int main()
{
string x;
cin >> x >> b;
la = x.size(); lc = la;
for (int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';
sub(c, a, b);
for (int i = lc - 1; i >= 0; i--) cout << c[i];
return 0;
}
4959

被折叠的 条评论
为什么被折叠?



