高精度计算
Posted xiaoyezi-wink
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高精度计算相关的知识,希望对你有一定的参考价值。
高精度计算
由于C++储存的最大整数是 long long 类型的,2^63左右,可是如果我们要计算的数超过了这个范围,那就会爆了,是时候引入高精度计算了。
高精度计算要把需要运算的数转化为字符串读入,否则会炸
高精度加法
思路:模拟竖式计算
注意:(1)进位
(2)倒序计算
#include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> using namespace std; char a1[10000],b1[10000]; int a[10000],b[10000],c[10000]; int main() { scanf("%s",a1); scanf("%s",b1);
int lena=strlen(a1); int lenb=strlen(b1);
for(int i=lena-1;i>=0;i--) a[lena-i]=a1[i]-‘0‘; //字符串转数字 for(int i=lenb-1;i>=0;i--) b[lenb-i]=b1[i]-‘0‘;
int len=max(lena,lenb);
for(int i=1;i<=len;i++) c[i]=a[i]+b[i]; for(int i=1;i<=len;i++) { c[i+1]+=c[i]/10; //处理进位 c[i]%=10; }
if(c[len+1]>0) len++; //处理最高位
for(int i=len;i>0;i--) printf("%d",c[i]);
return 0; }
高精度减法
思路:模拟竖式计算,进位变退位
注意:(1)大减小为负数
(2)借位减1
(3)strcmp(a1,b1),如果a1>b1,返回正数;a1=b1,返回0;a1<b1,返回负数
#include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> using namespace std; char a1[10000],b1[10000],c1[10000]; int a[10000],b[10000],c[10000]; int main() { scanf("%s",a1); scanf("%s",b1); if(strlen(a1)<strlen(b1)||strlen(a1)==strlen(b1)&&strcmp(a1,b1)<0) { strcpy(c1,a1); //把a1数组的值完全赋给c1 strcpy(a1,b1); strcpy(b1,c1); cout<<"-"; } int lena=strlen(a1); int lenb=strlen(b1); for(int i=lena-1;i>=0;i--) a[lena-i]=a1[i]-‘0‘; for(int i=lenb-1;i>=0;i--) b[lenb-i]=b1[i]-‘0‘; int len=max(lena,lenb); for(int i=1;i<=len;i++) { if(a[i]<b[i]) { a[i]+=10; //借位 a[i+1]--; } c[i]=a[i]-b[i]; } if(c[len]==0&&len>0) len--; //处理前导0 for(int i=len;i>0;i--) printf("%d",c[i]); return 0; }
高精度乘法
思路:模拟乘法竖式
注意:(1)判断结果正负0
(2)注意借位
#include<iostream> #include<cstdio> #include<cmath> #include<string> #include<cstring> #include<algorithm> using namespace std; char a1[200001],b1[200001]; int a[200001],b[200001],c[5000000],lena,lenb,lenc,x,i,j; int main() { scanf("%s",a1); scanf("%s",b1); if(a1[0]==‘0‘||b1[0]==‘0‘) { cout<<"0"; return 0; } lena=strlen(a1); lenb=strlen(b1); if(a1[0]==‘-‘&&b[0]!=‘-‘) { cout<<"-"; for(i=0;i<=lena-1;i++) a1[i]=a1[i+1]; lena--; } if(a1[0]!=‘-‘&&b[0]==‘-‘) { cout<<"-"; for(i=0;i<=lenb-1;i++) b1[i]=b1[i+1]; lenb--; } if(a1[0]==‘-‘&&b[0]==‘-‘) { for(i=0;i<=lena-1;i++) a1[i]=a1[i+1]; lena--; for(i=0;i<=lenb-1;i++) b1[i]=b1[i+1]; lenb--; } for(i=0;i<=lena-1;i++) a[lena-i]=a1[i]-‘0‘; for(i=0;i<=lenb-1;i++) b[lenb-i]=b1[i]-‘0‘; for(i=1;i<=lena;i++) { x=0; for(j=1;j<=lenb;j++) { c[i+j-1]=a[i]*b[j]+x+c[i+j-1]; x=c[i+j-1]/10; c[i+j-1]%=10; } c[i+lenb]=x; } lenc=lena+lenb; while(c[lenc]==0&&lenc>0) lenc--; for(i=lenc;i>=1;i--) cout<<c[i]; cout<<endl; return 0; }
高精度除法(常用高精度除以低精度)
思路:模拟除法式子
#include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> using namespace std; char str[50010]; int a[50010],c[50000000]; int main() { scanf("%s", str); int len=strlen(str); for(int i=len-1;i>=0;i--) a[len-i]=str[i]-‘0‘; int n=len; int B; cin>>B; for(int i=n;i>0;i--) { c[i]=a[i]/B; a[i-1]+=(a[i]%B)*10; } while(c[n]==0 && n>0) n--; for(int i=n;i>0;i--) printf("%d",c[i]); return 0; }
优化
举个栗子
在高精度加法
1 2 3 4 5 6 7 8 +
1 2 3 4 5 6 7 8 时
我们可以把1234存在一个数组格子里,最后就是%1000或者/1000了,只需要计算两次加法,提高效率,其他运算同理可以优化
以上是关于高精度计算的主要内容,如果未能解决你的问题,请参考以下文章