[C++] 高精度加法(作用 + 模板 + 例题)
高精度加法-目录
- 高精度加法用途
- 高精度加法模板
- string转数位数组
- int 转数位数组(附加型知识点)
- 高精度输出
- 高精度加法
- 函数大合集!!!
高精度加法用途
高精度加法通常用于加很大的数(真的很大, 超unsigned long long的那种).
高精度加法模板
注: 本篇数组下标0(x[0]
)存储的是该数组的有效位数.
string转数位数组
我们一般使用string
类型存储很大的数.
这个时候, 高精度加法要干的是模拟列竖式, 把每一位加起来, 然后再考虑进位的问题. 模拟列竖式需要数位末尾对齐, 所以我们最好把原始数据反转一下.
考虑以上两点, 需要先把string转换成int数位数组. 在这里我们以普通int数组举例, 除此之外还能用vector
或者short数组或者继续用string
也行.
// 头文件
#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
拆位实现.
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;
}
后续代码会把这段加上, 但可能不会再用.
高精度输出
我们先把辅助的代码讲完. 我们完成加法后, 我们肯定要把它输出出来, 由于是反着计算的, 所以要反着输出. 这个时候我们就需要高精度输出. 我们实现的功能是把进入函数的数组反向输出.
本段代码整合了上一段的代码.
#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;
}
高精度加法
分为以下部分:
- 写入有效长度
- 对应位数求和
- 处理进位情况
- 根据最高位更新长度
#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;
}
函数大合集!!!
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]++;}
}