zoukankan      html  css  js  c++  java
  • 完整版高精度计算(整理后的)

    转载请注明出处: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提交完整程序得出本文,能保证本文所有代码正确。

  • 相关阅读:
    unittest learning
    C++类和对象
    Linux shell基础(十二)
    Linux shell基础(十一)
    Linux shell基础(十)
    Linux shell基础(九)
    Linux shell基础(八)
    Linux shell基础(六)
    Linux shell基础(七)
    Linux shell基础(五)
  • 原文地址:https://www.cnblogs.com/zhishoumuguinian/p/8443829.html
Copyright © 2011-2022 走看看