高精度加法-目录
高精度加法用途
高精度加法通常用于加很大的数(真的很大, 超unsigned long long的那种).
高精度加法模板
注: 本篇数组下标0(x[0]
)存储的是该数组的有效位数.
string转数位数组
我们一般使用string
类型存储很大的数.
这个时候, 高精度加法要干的是模拟列竖式, 把每一位加起来, 然后再考虑进位的问题 . 模拟列竖式需要数位末尾对齐 , 所以我们最好把原始数据反转一下.
考虑以上两点, 需要先把string转换成int数位数组. 在这里我们以普通int数组举例, 除此之外还能用vector
或者short数组或者继续用string
也行.
cpp
// 头文件
#include <iostream>
#include <string>
using namespace std;
// **** 重点!!! ****
// 一般我们用'2'表示英语单词'to'
void s2BIG(string s, int a[]){
int len = s.size();
for(int i = 1; i <= len; i++){
a[i] = s[len - i] - '0';
}
a[0] = len;
}
// 使用方法
int main(){
string s;
cin >> s;
s2BIG(s, A);
// ......
return 0;
}
int 转数位数组(附加型知识点)
这是一个特殊的点, 因为有时候我们要把int和所谓的BIG进行高精度运算, 这时我们需要把int转换为BIG(数位数组) .通过while
拆位实现.
cpp
void i2BIG(int n, int a[]){
int cur = 0;
while(n > 0){
cur++;
a[cur] = n % 10;
n /= 10;
}
if(cur == 0) cur++;
a[0] = cur;
}
后续代码会把这段加上, 但可能不会再用.
高精度输出
我们先把辅助的代码讲完. 我们完成加法后, 我们肯定要把它输出出来, 由于是反着计算的, 所以要反着输出. 这个时候我们就需要高精度输出. 我们实现的功能是把进入函数的数组反向输出 .
本段代码整合了上一段的代码.
cpp
#include <iostream>
#include <string>
using namespace std;
int a[1005];
void s2BIG(string s, int a[]){
int len = s.size();
for(int i = 1; i <= len; i++){
a[i] = s[len - i] - '0';
}
a[0] = len;
}
void i2BIG(int n, int a[]){
int cur = 0;
while(n > 0){
cur++;
a[cur] = n % 10;
n /= 10;
}
if(cur == 0) cur++;
a[0] = cur;
}
void printBIG(int a[]){
int len = a[0];
for(int i = len; i > 0; i--){
cout << a[i];
}
cout << endl;
}
int main(){
string s;
cin >> s;
s2BIG(s, a);
printBIG(a);
return 0;
}
高精度加法
分为以下部分:
- 写入有效长度
- 对应位数求和
- 处理进位情况
- 根据最高位更新长度
cpp
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int x[1005], y[1005], z[1005];
void s2BIG(string s, int a[]){
int len = s.size();
for(int i = 1; i <= len; i++){
a[i] = s[len - i] - '0';
}
a[0] = len;
}
void i2BIG(int n, int a[]){
int cur = 0;
while(n > 0){
cur++;
a[cur] = n % 10;
n /= 10;
}
if(cur == 0) cur++;
a[0] = cur;
}
void printBIG(int a[]){
int len = a[0];
for(int i = len; i > 0; i--){
cout << a[i];
}
cout << endl;
}
/**** 新增 ****/
void addBIG(int x[], int y[], int z[]){
z[0] = max(x[0], y[0]); // 先写出有效长度
for(int i = 1; i <= z[0]; i++) // 对应位求和
z[i] = x[i] + y[i];
for(int i = 1; i <= z[0]; i++){ // 处理进位
z[i + 1] += z[i] / 10;
z[i] %= 10;
if(z[z[0] + 1] != 0) // 处理最高位进位, 更新有效位数
z[0]++;
}
}
int main(){
string a, b;
cin >> a >> b;
s2BIG(a, x);
s2BIG(b, y);
addBIG(x, y, z);
printBIG(z);
return 0;
}
函数大合集!!!
cpp
void s2BIG(string s, int a[]){
int len = s.size();
for(int i = 1; i <= len; i++){
a[i] = s[len - i] - '0';
}
a[0] = len;
}
void i2BIG(int n, int a[]){
int cur = 0;
while(n > 0){
cur++;
a[cur] = n % 10;
n /= 10;
}
if(cur == 0) cur++;
a[0] = cur;
}
void printBIG(int a[]){
int len = a[0];
for(int i = len; i > 0; i--){
cout << a[i];
}
cout << endl;
}
void addBIG(int x[], int y[], int z[]){
z[0] = max(x[0], y[0]); // 先写出有效长度
for(int i = 1; i <= z[0]; i++) // 对应位求和
z[i] = x[i] + y[i];
for(int i = 1; i <= z[0]; i++){ // 处理进位
z[i + 1] += z[i] / 10;
z[i] %= 10;
if(z[z[0] + 1] != 0) // 处理最高位进位, 更新有效位数
z[0]++;
}
}