# 高精度算法 ## 应用场景 利用计算机进行数值计算,有时会遇到这样的问题:有些计算要求精度高,希望计算的数的位数可达几十位甚至几百位,虽然计算机的计算精度也算较高了,但因受到硬件的限制,往往达不到实际问题所要求的精度。我们可以利用程序设计的方法去实现这样的高精度计算。 > 本节介绍常用的几种高精度计算的方法。 ## 算法的难点 ### 1. 数据的接收方法和存贮方法 数据的接收和存贮:当输入的数很长时: + 可采用字符串方式输入,这样可输入数字很长的数,利用字符串函数和操作运算,将每一位数取出,存入数组中。 ``` c++ void init(int a[]) //传入一个数组 { string s; cin>>s; //读入字符串s a[0]=s.length(); //用a[0]计算字符串s的位数 for(i=1;i<=a[0];i++) a[i]=s[a[0]-i]-'0'; //将数串s转换为数组a,并倒序存储 } ``` + 另一种方法是直接用循环加数组方法输入数据。 ### 2.高精度数位数的确定 位数的确定:接收时往往是用字符串的,所以它的位数就等于字符串的长度。 ### 3.进位,借位处理 **加法进位:** ``` c++ c[i]=a[i]+b[i]; if (c[i]>=10) { c[i]%=10; ++c[i+1]; } ``` **减法借位:** ``` c++ if (a[i] #include #include using namespace std; int main() { char a1[100],b1[100]; int a[100],b[100],c[100],lena,lenb,lenc,i,x; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); gets(a1); gets(b1); //输入加数与被加数 lena=strlen(a1); lenb=strlen(b1); for (i=0;i<=lena-1;i++) a[lena-i]=a1[i]-48; //加数放入a数组   for (i=0;i<=lenb-1;i++) b[lenb-i]=b1[i]-48; //加数放入b数组 lenc =1; x=0; while (lenc <=lena||lenc <=lenb) {    c[lenc]=a[lenc]+b[lenc]+x; //两数相加    x=c[lenc]/10;    c[lenc]%=10; lenc++; } c[lenc]=x; if (c[lenc]==0) lenc--; //处理最高进位 for (i=lenc;i>=1;i--) cout< #include #include using namespace std; int main() { int a[256],b[256],c[256],lena,lenb,lenc,i; char n[256],n1[256],n2[256]; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); printf("Input minuend:"); gets(n1); //输入被减数 printf("Input subtrahend:"); gets(n2); //输入减数 if (strlen(n1)n2时,返回正整数;n11)) lenc--; //最高位的0不输出   for (i=lenc;i>=1;i--) cout< #include #include using namespace std; int main() { char a1[100],b1[100]; int a[100],b[100],c[100],lena,lenb,lenc,i,j,x; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); gets(a1);gets(b1); lena=strlen(a1);lenb=strlen(b1); for (i=0;i<=lena-1;i++) a[lena-i]=a1[i]-48; for (i=0;i<=lenb-1;i++) b[lenb-i]=b1[i]-48; 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>1) //删除前导0 lenc--; for (i=lenc;i>=1;i--) cout< #include #include using namespace std; int main() { char a1[100],c1[100]; int a[100],c[100],lena,i,x=0,lenc,b; memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); gets(a1); cin>>b; lena=strlen(a1); for (i=0;i<=lena-1;i++)    a[i+1]=a1[i]-48; for (i=1;i<=lena;i++) //按位相除 { c[i]=(x*10+a[i])/b; x=(x*10+a[i])%b; }   lenc=1; while (c[lenc]==0&&lenc #include using namespace std; int a[101],b[101],c[101],d,i; void init(int a[]) { string s; cin>>s; //读入字符串s a[0]=s.length(); //用a[0]计算字符串 s的位数 for(i=1;i<=a[0];i++) a[i]=s[a[0]-i]-'0'; //将数串s转换为数组a,并倒序存储. } void print(int a[]) //打印输出 { if (a[0]==0){cout<<0<0;i--) cout<b则为1,ab[0]) return 1; //a的位数大于b则a比b大 if(a[0]0;i--) //从高位到低位比较 { if (a[i]>b[i]) return 1; if (a[i]0&&a[a[0]]==0) a[0]--; //修正a的位数 return; } } void chugao(int a[],int b[],int c[]) { int tmp[101]; c[0]=a[0]-b[0]+1; for (int i=c[0];i>0;i--) { memset(tmp,0,sizeof(tmp)); //数组清零 numcpy(b,tmp,i); while(compare(a,tmp)>=0){c[i]++;jian(a,tmp);} //用减法来模拟 } while(c[0]>0&&c[c[0]]==0)c[0]--; return ; } int main() { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); init(a);init(b); chugao(a,b,c); print(c); print(a); return 0; } ```