1. 程式人生 > >(轉)大數運算(4)——大數乘法

(轉)大數運算(4)——大數乘法

相加 算法 mark ces nts string.h views 刪除 當前

轉自:http://blog.csdn.net/lisp1995/article/details/52316466

首先說一下乘法計算的算法:同樣是模擬人工計算時的方法。
從低位向高位乘,在豎式計算中,我們是將乘數第一位與被乘數的每一位相乘,記錄結果之後,用第二位相乘,記錄結果並且左移一位,以此類推,直到計算完最後一位,再將各項結果相加,得出最後結果。
計算的過程基本上和小學生列豎式做乘法相同。為編程方便,並不急於處理進位,而將進位問題留待最後統一處理。
我們以125*53為例來說明計算過程:

1、先算125*3,3*5得到15個1,3*2得到6個10,3*1得到3個100;

技術分享圖片

2、接下來算125*5,5*5得到25個10,2*5得到10個100,5*1得到5個1000;

技術分享圖片

3、乘法過程完畢。接下來從 a[0]開始向高位逐位處理進位問題。a[0]留下5,把1 加到a[1]上,a[1]變為32 後,應留下2,把3 加到a[2]上……最終使得a裏的每個元素都是1 位數,結果就算出來了

技術分享圖片

結果就是6625。

總結一個規律:即一個數的第i 位和另一個數的第j 位相乘所得的數,一定是要累加到結果的第i+j 位上。這裏i, j 都是從右往左,從0 開始數。
即:ans[i+j] = a[i]*b[j];

另外進位時要處理,當前的值加上進位的值再看本位數字是否又有進位;前導清零。

下面是C語言代碼實現:

[cpp] view plain copy
    1. #include<stdio.h>
    2. #include<string.h>
    3. #define MAX 100
    4. char a[MAX],b[MAX];//用字符串進行數字的輸入
    5. int x[MAX+10],y[MAX+10],z[MAX*2+10];//積的位數最多是因數位數的兩倍
    6. int main()
    7. {
    8. int len1,len2,i,j;
    9. while(~scanf("%s %s",a,b))
    10. {
    11. len1=strlen(a);
    12. len2=strlen(b);
    13. for(j=0,i=len1-1;i>=0;i--)//將字符串中字符轉化為數字,並倒序儲存
    14. x[j++]=a[i]-‘0‘;
    15. for(j=0,i=len2-1;i>=0;i--)
    16. y[j++]=b[i]-‘0‘;
    17. for(i=0;i<len1;i++)//將因數各個位上的數字與另一個各個位上的數字相乘
    18. {
    19. for(j=0;j<len2;j++)
    20. z[i+j]=z[i+j]+x[i]*y[j];//先乘起來,後面統一進行進位
    21. }
    22. for(i=0;i<MAX*2;i++)//進行進位
    23. {
    24. if(z[i]>=10) //若>=10
    25. {
    26. z[i+1]=z[i+1]+z[i]/10; //將十位上數字進位
    27. z[i]=z[i]%10; //將個位上的數字留下
    28. }
    29. }
    30. for(i=MAX*2;i>0;i--) //刪除0的前綴
    31. {
    32. if(z[i]==0)
    33. continue;
    34. else
    35. break;
    36. }
    37. for(;i>=0;i--) //倒序輸出
    38. printf("%d",z[i]);
    39. printf("\n");
    40. }
    41. return 0;
    42. }

(轉)大數運算(4)——大數乘法