4、 大数,高精度计算---大数加法

来源:互联网 发布:互盾数据恢复软件 编辑:程序博客网 时间:2024/05/16 06:05

大数是算法语言中的数据类型无法表示的数,其位数超过最大数据类型所能表示的范围,所以,在处理大数问题时首先要考虑的是怎样存储大数,然后是在这种存储方式下其处理的实现方法。

一般情况下大数的存储是采用字符数组来存储,即将大数当作一个字符串来存储,而对其处理是按其处理规则在数组中模拟实现。


一  大数加法。

思路很常规。先用字符数组录入大数,(这个时候高位存在数组下标小的位置。  如:最高位在arr[0]处。  ---输入方式原因)  

然后再从高往低反向存入整数数组中。(使得低位在数组下标小的位置,符合常规。)

然后在进行计算,考虑进位情况。

加法比较简单,就不多说什么了。  直接上代码。


[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #define MAXLEN 1000  
  4.   
  5. int main()  
  6. {  
  7.     char a1[MAXLEN];  
  8.     char a2[MAXLEN];  
  9.     static int v1[MAXLEN];  
  10.     static int v2[MAXLEN];  
  11.     static int v3[MAXLEN];  
  12.     int i,j,n,L,z;  
  13.   
  14.     scanf("%d",&n);      //读入计算的组数  
  15.     for (j=0;j<n;j++)  
  16.     {  
  17.         scanf("%s%s",a1,a2);   //读入每组计算的2个大数  
  18.   
  19.         L=strlen(a1);  
  20.         for (i=0;i<L;i++)  
  21.             v1[i]=a1[L-1-i]-'0';      //大数a1反向  
  22.   
  23.         L=strlen(a2);  
  24.         for (i=0;i<L;i++)  
  25.             v2[i]=a2[L-1-i]-'0';   //大数a2反向  
  26.   
  27.         for (i=0;i<MAXLEN;i++)  
  28.             v3[i]=v1[i]+v2[i];       //a1.a2各位直接相加,先不考虑进位  
  29.   
  30.         for (i=0;i<MAXLEN;i++)  
  31.         {  
  32.             if (v3[i]>=10)  
  33.             {  
  34.                 v3[i+1]+=v3[i]/10;      //对每位进行进位处理  
  35.                 v3[i]=v3[i]%10;  
  36.             }  
  37.         }  
  38.   
  39.         printf("Case %d:\n", j+1);  
  40.         printf("%s + %s = ", a1, a2);  
  41.   
  42.         z=0;  
  43.         for (i=MAXLEN-1;i>=0;i--)           //打印  
  44.         {  
  45.             if (z==0)  
  46.             {  
  47.                 if (v3[i]!=0)  
  48.                 {  
  49.                     printf("%d",v3[i]);  
  50.                     z=1;  
  51.                 }  
  52.             }  
  53.             else  
  54.             {  
  55.                 printf("%d",v3[i]);  
  56.             }  
  57.         }  
  58.         if (z==0) printf("0");  
  59.   
  60.         printf("\n");  
  61.     }  
  62.     return 0;  
  63. }  


其实,上述代码还能进一步简化,合并操作步骤。

可以将大数的颠倒过程和求和运算过程合并,颠倒的过程是逐位移动到整数数组的过程,在移位的过程中,同时实现运算,但此时依旧先不考虑进位,所有各位的进位都在计算完成后统一处理。


[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. int main()  
  5. {  
  6.     char s[202];    //  假设大数不超过200位。    
  7.     int sum[201];  
  8.     int i, j, d, len, maxlen=0;  
  9.   
  10.     for (i=0;i<201;i++)        //对各位和进行初始化  
  11.     {  
  12.         sum[i] = 0;  
  13.     }  
  14.     for (i=0;i<2;i++)   // 读入两个大数  
  15.     {  
  16.         scanf("%s", s);  
  17.         len = strlen(s);  
  18.         if (len>maxlen)  
  19.             maxlen = len;  
  20.         for (j=len-1;j>=0;j--)  
  21.             sum[len-1-j] += s[j] - '0';         //颠倒求和,存入结果数组sum中  
  22.     }  
  23.   
  24.     for (i=0,d=0;i<maxlen;i++)   //从低位开始处理结果中的进位  
  25.     {  
  26.         sum[i] += d;  
  27.         d = sum[i] / 10;  
  28.         sum[i] %= 10;  
  29.     }  
  30.   
  31.     if (d>0)  
  32.         sum[maxlen++] += d;         //如果最后一个有进位,再往前挪一位  
  33.     for (i=maxlen-1;i>=0;i--)  
  34.         s[maxlen-1-i] = sum[i] + '0';       //结果以字符串方式保存  
  35.     s[maxlen] = '\0';  
  36.     printf("%s\n",s);         //输出结果  
  37.   
  38.     return 0;  
  39. }  

0 0
原创粉丝点击