高精度运算
一、使用背景
在进行数字计算的时候int、long long型范围终归是有限的,当计算数据或计算结果超出了基础数据类型的范围,我们通常就要使用高精度算法了。从方法上来看,高精度本质上就是我们平常数据计算进行模型归纳,通过模拟分析它的数学计算原理获得代码。
二、A+B Problem
解决A+B类型的题目使用的就是小学学到的竖式加法,竖式加法就是模拟每一位的加法和进位。现举一个例子来解释这个过程。
例如:478+576
\\代码:
#include<bits/stdc++.h>
#define maxn 500
using namespace std;
int a[maxn], b[maxn], c[maxn];
int main(){
string A, B;
cin >> A >> B;
int length = max(A.length(), B.length());//获得A和B中位数
for(int i = A.length() - 1, j = 1; i >= 0; i--, j++)
a[j] = A[i] - '0'; //将A中个位放在数组第一位并以此类推
for(int i = B.length() - 1, j = 1; i >= 0; i--, j++)
b[j] = B[i] - '0'; //将B中个位放在数组第一位并以此类推
for(int i = 1; i <= length; i++){
c[i] += a[i] + b[i];
c[i + 1] = c[i] / 10;//模拟进位
c[i] %= 10;
}
if(c[length + 1])// 最高位可能会进位,这里要做一个判断,如果进位了c[length + 1]由0变为非0
length++;
for(int i = length; i >= 1; i--)
cout << c[i];
}
三、A*B Problem
解决A+B类型的题目使用的就是小学学到的竖式乘法,竖式乘法就是模拟每一位的乘法和进位。现举一个例子来解释这个过程。
例如:478*576
\\代码:
#include<bits/stdc++.h>
#define maxn 5000
using namespace std;
int a[maxn], b[maxn], c[maxn];
int main(){
string A, B;
cin >> A >> B;
int lengtha = A.length(), lengthb = B.length();
for(int i = lengtha - 1; i >= 0; i--)
a[lengtha - i] = A[i] - '0';
for(int i = lengthb - 1; i >= 0; i--)
b[lengthb - i] = B[i] - '0';
for(int i = 1; i <= lengtha; i++)
for(int j = 1; j <= lengthb; j++)
c[i + j - 1] += a[i] * b[j]; //计算每一位的值,结果的i + j - 1位由a的i位和b的j位决定
int length = lengtha + lengthb; //乘积的位数不会超过两数位数之和
for(int i = 1; i <= length; i++){
c[i + 1] += c[i] / 10; //处理进位
c[i] %= 10;
}
for(; !c[length]; )
length--; //处理结果前多余的0
for(int i = max(1, length); i >= 1; i--) //0*0的情况length为0,此时要用max输出0
cout << c[i];
}
四、总结
本文用到的方法其实就是对竖式加法和竖式乘法的模拟并用代码实现,代码中需要注意的地方用注释写出,通过分析代码可以看出算法的复杂度是n的平方(n为位数),位数较大时计算速度还是较慢。如果要是运算速度加快可以去参考快速傅里叶变换。
现,代码中需要注意的地方用注释写出,通过分析代码可以看出算法的复杂度是n的平方(n为位数),位数较大时计算速度还是较慢。如果要是运算速度加快可以去参考快速傅里叶变换。