转载请注明出处:http://www.cnblogs.com/zhishoumuguinian/p/8443829.html
注:本文思路来源于Angle_Kitty,里边代码有些问题,经过整理和在oj提交完整程序得出本文,能保证本文所有代码正确。
高精度计算通用方法:高精度计算时一般用一个数组来存储一个数,数组的一个元素对应于数的一位(当然,在以后的学习中为了加快计算速度,也可用数组的一个元素表示数的多位数字,暂时不讲),表示时,由于数计算时可能要进位,因此为了方便,将数由低位到高位依次存在数组下标对应由低到高位置上,另外,我们申请数组大小时,一般考虑了最大的情况,在很多情况下,表示有富余,即高位有很多0,可能造成无效的运算和判断,因此,我们一般将数组的第0个下标对应位置来存储该数的位数.如数:3485(三千四百八十五),表达在数组a[10]上情况是:
下标 0 1 2 3 4 5 6 7 8 9
内容 4 5 8 4 3 0 0 0 0 0
说明:位数 个位 十位 百位 千位
注:高精度计算时一般用正数,对于负数,通过处理符号位的修正.
一.高精度存储
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 int main() 5 { 6 int a[250]={0};//开一个数组,全部置为0 7 int i; 8 string s1; 9 cin>>s1;//数s1 10 a[0]=s1.length(); //位数 11 for(i=1; i<=a[0]; i++) 12 a[i]=s1[a[0]-i]-'0';//将字符转为数字并倒序存储. 13 return 0; 14 }
二.高精度加法
1 #include <iostream> 2 #include<string> 3 4 using namespace std; 5 6 int main() 7 { 8 string s1, s2; 9 int a[250]={0}, b[250]={0}; 10 int i, j; 11 cin>>s1>>s2; 12 a[0]=s1.length(); 13 //cout<<a[0]<<endl; 14 b[0]=s2.length(); 15 //cout<<b[0]<<endl; 16 for(i=1; i<=a[0]; i++) 17 { 18 a[i]=s1[a[0]-i]-'0'; 19 } 20 for(i=1; i<=b[0]; i++) 21 { 22 b[i]=s2[b[0]-i]-'0'; 23 } 24 int k=max(a[0],b[0]); 25 for(i=1; i<=k; i++) 26 { 27 a[i+1]+=(a[i]+b[i])/10; 28 a[i]=(a[i]+b[i])%10; 29 } 30 if(a[k+1]>0) a[0]=k+1; 31 else a[0]=k;//前边是正常的大数加法 32 while(a[a[0]]==0&&a[0]>0)//除去多余的0 33 { 34 a[0]--; 35 } 36 if(a[0]==0)//如果把零都除没了,那就是0了 37 cout<<0; 38 else 39 for(j=a[0]; j>0; j--) 40 { 41 cout<<a[j]; 42 } 43 }
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int main() 6 { 7 string s1, s2; 8 cin>>s1>>s2; 9 int i; 10 11 int s1len=s1.length();//数的长度 12 int s2len=s2.length(); 13 int s1befor=s1.find(".");//整数长度 14 int s2befor=s2.find("."); 15 int s1after=s1len-s1befor-1;//小数长度 16 int s2after=s2len-s2befor-1; 17 int maxp=max(s1after,s2after);//最长小数长度 18 int maxi=max(s1befor, s2befor); 19 reverse(s1.begin(), s1.end());//倒置 20 reverse(s2.begin(), s2.end()); 21 22 int pp1=s1.find("."), pp2=s2.find("."); 23 if(pp1<pp2)//将小数点对齐 24 { 25 for(int i=0; i<pp2-pp1; i++) 26 { 27 s1="0"+s1; 28 } 29 s1.erase(pp2,1);//对齐后删除小数点 30 s2.erase(pp2,1); 31 } 32 if(pp2<=pp1) 33 { 34 for(int i=0; i<pp1-pp2; i++) 35 { 36 s2="0"+s2; 37 } 38 s1.erase(pp1,1); 39 s2.erase(pp1,1); 40 } 41 42 int a[200]={0}, b[200]={0}; 43 a[0]=s1.length(); 44 b[0]=s2.length(); 45 for(i=1; i<=a[0]; i++)//将数装到数组里 46 { 47 a[i]=s1[i-1]-'0'; 48 49 } 50 for(i=1; i<=b[0]; i++) 51 { 52 b[i]=s2[i-1]-'0'; 53 54 } 55 int k=max(a[0], b[0]);//做个大数加法 56 for(i=1; i<=k ;i++) 57 { 58 a[i+1]+=(a[i]+b[i])/10; 59 a[i]=(a[i]+b[i])%10; 60 } 61 if(a[k+1]>0) 62 { 63 a[0]=k+1; 64 maxi++; 65 } 66 else 67 a[0]=k; 68 while(a[a[0]]==0&&a[0]>maxp+1)//除去整数前0 69 { 70 a[0]--; 71 maxi--;//除去一个零,整数长度减一 72 } 73 74 reverse(&a[1], &a[1]+a[0]); 75 while(a[a[0]]==0&&a[0]>maxi)//出去小数后边的0 76 { 77 a[0]--; 78 maxp--;//除去一个0,小数长度减一 79 } 80 81 for(i=1; i<=a[0]; i++) 82 { 83 cout<<a[i]; 84 if(i==maxi&&a[0]>maxi) 85 cout<<"."; 86 } 87 }
三.高精度减法
1 #include<bits/stdc++.h> 2 #include<string> 3 using namespace std; 4 5 int main() 6 { 7 string s1, s2; 8 while(cin>>s1>>s2) 9 { 10 int a[250]= {0}, b[250]= {0}; 11 a[0]=s1.length(); 12 b[0]=s2.length(); 13 int i; 14 for(i=1; i<=a[0]; i++) 15 { 16 a[i]=s1[a[0]-i]-'0'; 17 } 18 for(i=1; i<=b[0]; i++) 19 { 20 b[i]=s2[b[0]-i]-'0'; 21 } 22 int flag=0; 23 for(i=max(a[0],b[0]); i>0; i--) 24 { 25 if(a[i]>b[i]) 26 { 27 flag=1; 28 break; 29 } 30 if(a[i]<b[i]) 31 { 32 flag=-1; 33 break; 34 } 35 } 36 37 if(flag==0) 38 { 39 memset(a,0,sizeof(a)); 40 a[0]=1; 41 } 42 if(flag==1) 43 { 44 for(i=1; i<=a[0]; i++) 45 { 46 if(a[i]<b[i]) 47 { 48 a[i+1]--; 49 a[i]+=10; 50 } 51 a[i]-=b[i]; 52 } 53 while(a[a[0]]==0) 54 a[0]--; 55 } 56 if(flag==-1) 57 { 58 for(i=1; i<=b[0]; i++) 59 { 60 if(b[i]<a[i]) 61 { 62 b[i+1]--; 63 b[i]+=10; 64 } 65 a[i]=b[i]-a[i]; 66 } 67 a[0]=b[0]; 68 while(a[a[0]]==0) 69 a[0]--; 70 } 71 if(flag==-1) 72 cout<<"-"; 73 for(i=a[0]; i>0; i--) 74 { 75 cout<<a[i]; 76 } 77 cout<<endl; 78 } 79 return 0; 80 }
四.高精度乘法
4.1大整数乘法
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int main() 5 { 6 string s1,s2; 7 cin>>s1>>s2; 8 int a[240]={0}, b[240]={0}, c[500]={0}; 9 a[0]=s1.length(); 10 b[0]=s2.length(); 11 c[0]=a[0]+b[0]+1; 12 int i, j; 13 for(i=1; i<=a[0]; i++) 14 { 15 a[i]=s1[a[0]-i]-'0'; 16 } 17 for(i=1; i<=b[0]; i++) 18 { 19 b[i]=s2[b[0]-i]-'0'; 20 } 21 for(i=1; i<=a[0]; i++) 22 { 23 for(j=1; j<=b[0]; j++) 24 { 25 c[i+j]+=a[i]*b[j]; 26 c[i+j+1]+=c[i+j]/10; 27 c[i+j]%=10; 28 } 29 } 30 while(c[c[0]]==0) 31 c[0]--; 32 if(c[0]<2) 33 cout<<0; 34 else 35 for(i=c[0]; i>1; i--) 36 { 37 cout<<c[i]; 38 } 39 }
4.2大数阶乘
1 #include <iostream> 2 #include <math.h> 3 #include <stdlib.h> 4 #include <string.h> 5 using namespace std; 6 7 int main() 8 { 9 int i; 10 int a[99999]={0}; 11 char n[20]; 12 cin>>n;//读进来一个数,保存为字符串 13 int m=atoi(n);//利用函数将字符串n转为整数m 14 if(m==0) 15 { 16 cout<<1; 17 return 0; 18 } 19 a[0]=strlen(n);//a[0]是数字位数 20 for(i=1; i<=a[0]; i++)//将n保存到a数组中,倒置 21 { 22 a[i]=n[a[0]-i]-'0'; 23 } 24 for(int j=m-1; j>0; j--)//n的阶乘的每位数,循环体就是高精度计算里的高精度数乘整数 25 { 26 for(i=1; i<=a[0]; i++)//先把每位乘 27 { 28 a[i]*=j; 29 } 30 for(i=1; i<=a[0]; i++) 31 { 32 a[i+1]+=a[i]/10;//进位 33 a[i]=a[i]%10; 34 } 35 while(a[i]>0)//处理最后一位数 36 { 37 a[i+1]+=a[i]/10; 38 a[i]=a[i]%10; 39 i++; 40 a[0]++; 41 } 42 } 43 for(i=a[0]; i>0; i--)//到着输出 44 { 45 cout<<a[i]; 46 } 47 }
五.高精度除法
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 int mult(int *a, int *b) 5 { 6 int i, j; 7 int flag=0; 8 for(i=max(a[0], b[0]); i>0; i--) 9 { 10 if(a[i]>b[i]) 11 { 12 flag=1; 13 break; 14 } 15 if(a[i]<b[i]) 16 { 17 flag=-1; 18 break; 19 } 20 } 21 if(flag==-1) return -1;//处理小于等于情况 22 if(flag==0) return 0; 23 24 int k=b[0];//将 b 的长度保留下来 25 26 //reverse(&b[1],&b[1]+b[0]);//扩大倍数 27 if(a[a[0]]>b[b[0]]) 28 { 29 reverse(&b[1],&b[1]+b[0]);//扩大倍数 30 b[0]+=(a[0]-b[0]);//比如3200和20 31 } 32 else 33 { 34 reverse(&b[1],&b[1]+b[0]);//扩大倍数 35 b[0]+=(a[0]-b[0]-1) ; 36 } 37 reverse(&b[1],&b[1]+b[0]); 38 39 for(i=1; i<=a[0]; i++)//做个减法 40 { 41 if(a[i]<b[i]) 42 { 43 a[i+1]--; 44 a[i]+=10; 45 } 46 a[i]-=b[i]; 47 } 48 while(a[a[0]]==0) 49 a[0]--; 50 51 52 53 int m=b[0]-k+1;//扩大倍数 54 reverse(&b[1],&b[1]+b[0]); 55 b[0]=k; 56 reverse(&b[1],&b[1]+b[0]); 57 return m; 58 } 59 60 int main() 61 { 62 string s1,s2; 63 cin>>s1>>s2; 64 int a[200]= {0},b[200]= {0}; 65 a[0]=s1.length(); 66 b[0]=s2.length(); 67 int i,j,t; 68 69 for(i=1; i<=a[0]; i++) 70 { 71 a[i]=s1[a[0]-i]-'0'; 72 } 73 while(a[a[0]]==0) 74 a[0]--; 75 for(i=1; i<=b[0]; i++) 76 { 77 b[i]=s2[b[0]-i]-'0'; 78 } 79 while(b[b[0]]==0) 80 b[0]--;/*读入数据并清除前导0,比如000003*/ 81 82 if(b[0]<1)//b为0的情况 83 { 84 return 0; 85 } 86 87 int c[200]= {0}; c[0]=1;//c数组用来保存结果 88 int d[250]= {0}; d[0]=1;//d数组用来保存临时返回结果 89 90 while(1) 91 { 92 t=mult(a,b);//做减法 93 if(t==-1) break;//被除数小于除数 94 if(t==0) d[1]=1;//被除数等于除数 95 else d[t]=1; 96 int k=max(c[0], t); 97 for(j=1; j<=k; j++) 98 { 99 c[j+1]+=(c[j]+d[j])/10; 100 c[j]=(c[j]+d[j])%10; 101 } 102 if(c[k+1]>0) c[0]=k+1; 103 else c[0]=k; 104 105 d[t]=0;//将d恢复 106 if(t==0) break; 107 } 108 for(i=c[0]; i>0; i--) 109 { 110 cout<<c[i]; 111 } 112 /* 113 cout<<endl; 114 cout<<"a余:"; 115 if(t==0) cout<<0; 116 else 117 for(i=a[0]; i>0; i--) 118 { 119 cout<<a[i]; 120 } 121 cout<<endl<<endl; 122 *//*注释部分为打印余数*/ 123 }
本文思路来源于http://www.cnblogs.com/ECJTUACM-873284962/p/6509429.html,经过整理和在oj提交完整程序得出本文,能保证本文所有代码正确。