6、大数,高精度计算---大数乘法

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

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

 三 大数乘法。

大数乘法,相对之前的加法和减法,难度有所提高,但是本质还是一样的。

下面说说我的方法:

1、利用字符数组读入大数a,b

2、将大数反向存储到整型数组中。(此时满足低位在数组下标小的位置上)

3、逐个相乘。   此时要注意 乘数i位和乘数j位的乘积,应累加在结果数组的i+j位上。  这个结论不难发现,可通过列个简单的竖式乘法验证。

4.、处理进位,(从低位开始到最高位逐位处理,将本位结果的个位作为该为的结果,而10位以上的数均作为进位进到上一位,一直到所有进位处理完)

5、然后整体再反向存入字符数组,打印出结果。

 

思路很常规,算法也比较简单,但是效率方面,可能不太理想。

水平有限,只能写出这样的代码。以后有能力了,再优化优化。

[cpp]  view plain copy
  1. #include<stdio.h>  
  2. #include<string.h>  
  3. #define MaxLen 1000  
  4. int main()  
  5. {  
  6.     char str_a[MaxLen], str_b[MaxLen], str_c[2*MaxLen];  
  7.     int num_a[MaxLen], num_b[MaxLen], num_c[2*MaxLen];  
  8.     int i, j, k, d, len_a, len_b;  
  9.   
  10.     while (scanf("%s%s",str_a,str_b)!=EOF)   //便于多次测试。  
  11.     {  
  12.         for (i=0; i<MaxLen; i++)   //初始化,清0  
  13.         {  
  14.             num_a[i] = 0;        
  15.             num_b[i] = 0;  
  16.         }  
  17.         for (i=0; i<2*MaxLen; i++)  
  18.             num_c[i] = 0;  
  19.         len_a = strlen(str_a);     //颠倒存储a,b两大数  
  20.         i = len_a - 1;  
  21.         k = 0;  
  22.         while ( i>=0 )  
  23.             num_a[k++] = str_a[i--] - '0';  
  24.   
  25.         len_b = strlen(str_b);  
  26.         i = len_b - 1;  
  27.         k = 0;  
  28.         while ( i>=0 )  
  29.             num_b[k++] = str_b[i--] - '0';  
  30.   
  31.         for ( i=0; i<len_a; i++ )   //先不考虑进位,对应加到结果数组num_c中  
  32.             for ( j=0; j<len_b; j++ )  
  33.                 num_c[i+j] += num_a[i] * num_b[j];  
  34.   
  35.         k = 2 * MaxLen - 1;  
  36.         while ( k>=0 && num_c[k]==0 )        //寻找最高位  
  37.             k--;  
  38.   
  39.         i = 0;  
  40.         d = 0;  
  41.         while( i<=k )    //处理进位  
  42.         {  
  43.             num_c[i] += d;    //加上对应位置的进位  
  44.             d = num_c[i] / 10;    //得到进位  
  45.             num_c[i] %= 10;    //得到对应位置结果  
  46.             i++;  
  47.         }  
  48.   
  49.         while ( d>0 )        //处理最高位进位  
  50.         {  
  51.             num_c[i] = d % 10;  
  52.             d = d / 10;  
  53.             i++;  
  54.         }  
  55.   
  56.         k = i;       //得到结果的最高位  
  57.         for ( i=k-1; i>=0; i-- )  
  58.             str_c[k-i-1] = num_c[i] + '0';    //结果转换成字符  
  59.         str_c[k] = '\0';  
  60.   
  61.         printf("%s\n",str_c);   //结果转换成字符串  
  62.     }  
  63.     return 0;  
  64.   
  65. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值