完整版高精度计算(整理后的)

转载请注明出处: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.1大整数加法

 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 }
View Code

1.2实数加法

 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 }
View Code

三.高精度减法

 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 }
View Code

 

四.高精度乘法

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 }
View Code

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 }
View Code

五.高精度除法

  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 }
View Code

 本文思路来源于http://www.cnblogs.com/ECJTUACM-873284962/p/6509429.html,经过整理和在oj提交完整程序得出本文,能保证本文所有代码正确。

原文地址:https://www.cnblogs.com/zhishoumuguinian/p/8443829.html