大数乘法运算

 

大数乘法运算

14人阅读 评论(0) 收藏 举报

有一种可能的问题就是,两个巨大无比的整型数要做乘法。例如:

1234567890*2234567890

这样的乘法结果无论当前的哪一个数据类型都不能单独表示。

于是,如果你遇到抽疯的面试官问你这样的问题,你可以这样做(假设只处理无符号数):

第一步,将两个运算数从各位到最高位都存在一个数组里

第二步,申请一个足够大的数组来存放结果,将数组的所有数据都初始化成0

第三步,实现累加器函数,该函数的输入是结果数组和一个下标以及被累加的数,函数的流程是:

对该数组的该下标的数据和被累加数进行加法运算,如果需要进位,则计算出进位值后下标增1递归调用累加函数实现向下一位的累加和进位(多位数的乘法最后不就是按照各个位的乘法结果进行累加和进位的么)。

第四步,从乘数的个位开始(0号下标),对被乘数进行每一位的乘法运算,每一位的运算结果带入累加器。

具体代码实现如下:

 

  1. #include <string.h>   
  2. /* 
  3.     将一个长整数的字符串变成字节数组,只能处理正整数 
  4.     参数: 
  5.     pszNumber           数字字符串 
  6.     nStrLen             数字字符串的ANSI编码的字符数,不包括 null结束符 
  7.     pBuffer             目标字节数组,如果为空,则由参数4返回所需要的大小 
  8.     nSize               目标字节数组的大小,如果为0或者空间不足,则返回所需要的大小 
  9.  
  10.     返回值: 
  11.     转换成功返回true,否则返回false。 
  12. */  
  13. bool PrepareNumberArray(const charconst pszNumber,size_t nStrLen,unsigned charconst pBuffer,size_t &nSize)  
  14. {  
  15.     /*参数合法性判断*/  
  16.     if(!pszNumber || nStrLen <= 0) return false;   
  17.     if(!pBuffer || nSize ==0 || nSize<nStrLen) { nSize = nStrLen;    return false;   }  
  18.     /*转化字符串到数组,0下标放置各位*/  
  19.     for(size_t i =0;i<nStrLen;i++)  
  20.     {  
  21.         if (pszNumber[i]>'9' || pszNumber[i]<'0'return false;   
  22.         pBuffer[nStrLen - i - 1] = pszNumber[i] - '0';  
  23.     }  
  24.     return true;  
  25. }  
  26. /* 
  27.     将一个数累加到当前结果数组的相应位上,如果需要进位,则将进位值累加到结果数组的下一位上 
  28.     参数: 
  29.     pResult             结果数组 
  30.     nSize               结果数组的总大小 
  31.     nPos                将结果累加到哪一位(个位为下标0) 
  32.     nNumToAdd           被累加数 
  33.  
  34.     返回值: 
  35.     成功返回true,否则返回false。 
  36. */  
  37. bool CarrayAdd(unsigned charconst pResult,const size_t nSize,size_t nPos,const unsigned char nNumToAdd)  
  38. {  
  39.     if(!pResult || nPos >= nSize) return false//参数不正确   
  40.     pResult[nPos] += nNumToAdd;  
  41.     unsigned char nCarry = pResult[nPos] / 10;  
  42.     pResult[nPos] %= 10;  
  43.     if (nCarry >0) return CarrayAdd(pResult,nSize,++nPos,nCarry);  
  44.     return true;  
  45. }  
  46. /* 
  47.     计算两个大数的乘法 
  48.     参数: 
  49.     pA              被乘数 
  50.     nALen           被乘数的位数(例如100是三位) 
  51.     pB              乘数 
  52.     nBLen           乘数的位数 
  53.     pResult         结果 
  54.     nSize           结果数组的大小,如果为0或者空间不足,则返回所需要的大小 
  55. */  
  56. bool BigIntMulti(const unsigned char* pA, const size_t nALen,const unsigned char* pB, const size_t nBLen,unsigned charconst pResult,size_t &nSize)  
  57. {  
  58.     if(!pA || !pB || nALen == 0 || nBLen == 0) return false//参数不合法   
  59.     if(!pResult || nSize ==0 || nSize<(nALen+nBLen +3)) {        nSize = nALen+nBLen+3;  return false;   }  
  60.     memset(pResult,0,nSize*sizeof(unsigned char)); //初始化结果数组   
  61.     for(size_t i =0; i<nBLen; i++)  
  62.     {  
  63.         for(size_t j =0; j<nALen; j++)  
  64.         {  
  65.             unsigned char nResult = pB[i] * pA[j];  
  66.             if(!CarrayAdd(pResult,nSize,i+j,nResult)) return false;  
  67.         }  
  68.     }  
  69.     return true;  
  70. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值