什么是高精度
有时,我们要做特别大数据的计算。多大呢?几百万位,远远超过了long long的数据范围,直接用long long肯定会溢出。这时候我们就要用高精度算法
PS:python自带高精度
所有高精度算法的基本原理
大体的思路,就是用字符数组(因为字符数组可以达到一个下标对应一个数字,达到按位处理的目的),然后转到整形数组(整型数组才能进行计算)一个下标对应一个数字,用另一个数组进行按位相加。
高精度运算
现在只写高精度加法、乘法。以后会逐渐补充
加法
思路分析
我们用数学竖式的方法来分析
别说这不是高精度,原理一样的,要不你来写个几百万位的竖式(防杠精)
这是小学数学的知识 对应位相加,有进位的加到下一位。
现在,按照刚才的思路进行模拟。仍然是134+84。但存到计算机中,再按位相加,变成了这样:
对于这种错位的情况,我们一般采取的办法是倒序存储。于是就是这样:
就是结果也是反着的。但是没关系,我们再进行倒序输出。218,没错!
代码
有了上面的说明,代码就很好懂了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include<iostream> #include<cstring> using namespace std; int main(){ int add1=0; int a[1000]={},b[1000]={},c[2000]; char a1[1000],b1[1000]; cin>>a1>>b1; for(int i=0;i<strlen(a1);i++){ a[strlen(a1)-1-i]=a1[i]-'0'; } for(int i=0;i<strlen(b1);i++){ b[strlen(b1)-1-i]=b1[i]-'0'; } for(int i=0;i<max(strlen(a1),strlen(b1));i++){ c[i]+=a[i]+b[i]; c[i+1]=c[i]/10; c[i]%=10; } if(c[max(strlen(a1),strlen(b1))]!=0){ add1=1; } for(int i=max(strlen(a1),strlen(b1))+add1-1;i>=0;i--){ cout<<c[i]; } return 0; }
|
乘法
思路分析
有了前边加法的基础,应该很容易想到,乘法也需要倒序存储。
这里我就不多说了。
需要解释的地方如下:
1.核心计算部分
高精度乘法,实际上就是用加法模拟乘法。用乘法分配律就很好懂:
123*45=123*(40+5)=123*40+123*5
在用高精度计算时,也是一样的,只是进位处理不一样。我们用一个新的数组存储答案(这里定为c[2000]={})==数组下标从1开始用==,c[1]+=3*5,c[1]+=2*5……,c[2]+=3*4,……
在我加粗的部分,很明显,不是从下标1开始了。原因很简单,自行列竖式理解
2.处理进位部分
这里处理进位的方法比较特殊,大体思路是把这一位除以10的结果加到下一位,并对这一位模10;下一位仍然这样,再下一位……
代码
再强调一次,此代码数组下标是从1开始用的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include<iostream> using namespace std; int main(){ string a1,b1; int a[2000]={},b[2000]={},c[5000]={}; cin>>a1>>b1; for(int i=1;i<=a1.length();i++){ a[i]=a1[a1.length()-i]-'0'; } for(int i=1;i<=b1.length();i++){ b[i]=b1[b1.length()-i]-'0'; } for(int i=1;i<=b1.length();i++){ for(int j=1;j<=a1.length();j++){ c[i+j-1]+=a[j]*b[i]; } } for(int i=1;i<a1.length()+b1.length();i++){ if(c[i]>9){ c[i+1]+=c[i]/10; c[i]%=10; } } int chu=a1.length()+b1.length(); while(c[chu]==0 && chu>1){ chu--; } for(int i=chu;i>=1;i--){ cout<<c[i]; } return 0; }
|