高精度计算(二):大整数乘法

本文深入探讨了高精度计算中的大整数乘法,介绍了一种高效算法,包括其原理、步骤和优缺点。通过对位操作和数学原理的应用,实现对大整数的精确乘法,适用于处理超过常规整型范围的数值计算问题。
摘要由CSDN通过智能技术生成
【例1】两个大整数乘法。
      输入两个不超过200位的非负大整数a和b,求a×b的值。
      (1)编程思路。
      用 unsigned num1[200]和num2[200]分别存放两个乘数,用result[400]来存放积。计算的中间结果也都存在result 中。result 长度取400 是因为两个200 位的数相乘,积最多会有400 位。num1[0], num2[0], result[0]都表示个位。
       计算的过程基本上和小学生列竖式做乘法相同。为编程方便,并不急于处理进位,而将
进位问题留待最后统一处理。
       图1给出了753×68的计算过程。描述如下:
      1)先依次计算753的各位数字与8的乘积,并加到result数组的相应单元中。result数组的全部元素的初始值均为0。
      2)再依次计算753的各位数字与6的乘积,并加到result数组的相应单元中。
      3)乘法过程完毕。从 result[0]开始向高位逐位处理进位问题。result[0]留下4,
把2 加到result[1]上,result[1]变为60 后,应留下0,把6 加到result[2]上……最终使
得result 里的每个元素都是1 位数,结果就算出来了。
       在乘法过程中,num1的第i 位和num2的第j 位相乘所得的数,一定是要累加到
result的第i+j 位上。这里i, j 都是从右往左,从0 开始数。
      (2)源程序。
#include <stdio.h>
#include <string.h>
#define MAX_LEN 201
void bigNumMul(char a[],char b[],char c[])
{
      int i,j,n1,n2;
      int num1[MAX_LEN]={0},num2[MAX_LEN]={0},result[2*MAX_LEN]={0};
      // 将a和b中存储的字符串形式的整数转换到num1和num2中去,
      // num1[0]对应于个位、num1[1]对应于十位、……
      n1 = strlen(a);
      j = 0;
     for (i = n1 - 1;i >= 0 ; i --)
        num1[j++] = a  - '0';
     n2 = strlen(b);
     j = 0;
    for (i = n2 - 1;i >= 0 ; i --)
        num2[j++] = b - '0';
    for (i=0;i < n2; i++ )
    {
        for (j=0; j<n1; j++)
            result[i+j] += num2*num1[j];   // 两数第i, j 位相乘,累加到结果的第i+j 位
    }
     //  统一处理进位问题
    for( i = 0; i < MAX_LEN * 2; i ++ ) {
         if (result >= 10)
         {
              result[i+1] += result / 10;
              result %= 10;
         }
    }
    bool isBeginZero = false;
    j=0;
    for (i=n1+n2-1; i>=0; i--)
         if (isBeginZero)
            c[j++]=result+'0';
        else if (result!=0)
        {
             c[j++]=result+'0';
              isBeginZero = true;
         }
    if (!isBeginZero) c[j++]='0';
    c[j]='\0';
}
int main()
{
     char a[MAX_LEN],b[MAX_LEN],c[2*MAX_LEN];
     scanf("%s",a);
     scanf("%s",b);
     bigNumMul(a,b,c);
     printf("%s\n",c);
     return 0;
}
(3)问题扩展。
下面我们来讨论如何完成一个大整数a和一个int型整型变量b的相乘。
图2给出了753×68的另一种计算过程。描述如下:
      
 

 

       1)先依次计算753的各位数字与68的乘积,并存入到result数组的相应单元中。
       2)乘法过程完毕。从 result[0]开始向高位逐位处理进位问题。result[0]留下4,
把20 加到result[1]上,result[1]变为360 后,应留下0,把36 加到result[2]上……最终使
得result 里的每个元素都是1 位数,结果就算出来了。
按这个思路可以实现一个大整数与int型整型变量相乘。源程序如下:
#include <stdio.h>
#include <string.h>
#define MAX_LEN 201
void bigNumMul(char a[],int b,char c[])
{
      int i,j,n1,n2,t;
      int num[MAX_LEN]={0},result[MAX_LEN+10]={0};
      // 将a和b中存储的字符串形式的整数转换到num1和num2中去,
      // num1[0]对应于个位、num1[1]对应于十位、……
      n1 = strlen(a);
      j = 0;
      for (i = n1 - 1;i >= 0 ; i --)
         num[j++] = a - '0';
      n2 =0;
      t=b;
      do {
           n2++;
           t=t/10;
       } while (t!=0);
       for (i=0;i < n1; i++)
            result = num*b;
       //   统一处理进位问题
       for (i = 0; i < n1+n2; i++)
       {
            if (result >= 10)
           {
                result[i+1] += result / 10;
                result %= 10;
            }
       }
      bool isBeginZero = false;
      j=0;
      for (i=n1+n2-1; i>=0; i--)
          if (isBeginZero)
             c[j++]=result+'0';
         else if (result!=0)
        {
            c[j++]=result+'0';
            isBeginZero = true;
         }
       if (!isBeginZero) c[j++]='0';
       c[j]='\0';
}
int main()
{
      char a[MAX_LEN],c[MAX_LEN+10];
       int b;
      scanf("%s",a);
       scanf("%d",&b);
       bigNumMul(a,b,c);
       printf("%s\n",c);
       return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值