大数相乘算法

来源:互联网 发布:天天向上网络作家专场 编辑:程序博客网 时间:2024/05/02 00:13

直接给代码

view plain
  1. ////////////////////////////////////////////////////////////////  
  2. //作者:涂远东  
  3. //时间:2010 01 23  
  4. //高精度的乘法,乘数的位数没有限制,小数点后面的位数也没有限制  
  5. //输入参数:乘数 str1,str2  
  6. //输出参数:str = str1*str2  
  7. //返回值类型:string&  
  8. ////////////////////////////////////////////////////////////////  
  9. string& large_mult(string str1,string str2,string& str/*输出参数*/)  
  10. {  
  11.     str = "0";  
  12.     int pos1 = str1.find('.');  
  13.     int pos2 = str2.find('.');  
  14.     //小数点在字符串的位置  
  15.     int offset = str1.length() + str2.length()  
  16.         - ((pos1 >0)? (pos1+1):0 )  
  17.         - ((pos2 >0) ? (pos2+1):0 );  
  18.     //去除字符串str1和str2中的小数点  
  19.     if(pos1 != -1)  
  20.         str1.erase(pos1,1);  
  21.     if(pos2 != -1)  
  22.         str2.erase(pos2,1);  
  23.     unsigned char single = 0;   //个位数  
  24.     unsigned char tens = 0; //十位数  
  25.     unsigned char ret = 0;  //乘积  
  26.     //计算规则,假设str1和str2字符串长度分别为len1和len2  
  27.     //乘积str的字符串长度len应该不大于len1+len2  
  28.     //乘数str1[len1-i]和str2[len2-j]相乘只会乘积中str中str[len-i-j]和str[len-i-j-1]的值  
  29.     int i = 0;  
  30.     for(string::iterator iter = str1.end()-1; iter >= str1.begin(); iter--,i++)  
  31.     {  
  32.         int index = 0;  
  33.         int offset = 0;  
  34.         int j=0;  
  35.         for(string::iterator iter2=str2.end()-1; iter2 >= str2.begin(); iter2--,j++)  
  36.         {  
  37.             offset = i+j +1;  
  38.             //字符‘0’的ASCII编码值为48  
  39.             ret = (*iter2 -'0') * (*iter -'0'); //乘积  
  40.             single = ret % 10;      //乘积的个位数  
  41.             tens = ret / 10;        //乘积的十位数  
  42.               
  43.             //位数不够左边补0  
  44.             index = str.length() - offset;  
  45.             while(index < 1)  
  46.             {  
  47.                 str.insert(str.begin(), '0');  
  48.                 index = str.length() - offset;  
  49.             }  
  50.             assert(str.length() > offset);  
  51.             index = str.length() - offset;  
  52.       
  53.             add(str,index,single);      //个位数相加  
  54.             add(str,index-1,tens);      //十位数相加  
  55.         }  
  56.     }  
  57.     if(str[0] == '0')  
  58.     {  
  59.         str.erase(str.begin());  
  60.     }  
  61.     if(offset < str.length())  
  62.     {  
  63.         string::iterator itr = str.end()-offset;  
  64.         str.insert(itr,'.');  
  65.     }  
  66.     return str;  
  67. }  
  68. ////////////////////////////////////////////////////////////////  
  69. //在大数str的index位处加于num 即 str+= num  
  70. ////////////////////////////////////////////////////////////////  
  71. inline bool add(string& str, int index, int num)  
  72. {     
  73.     assert(index >=0);  
  74.     int  p = str[index] + num - '0';      
  75.       
  76.     str[index] = p%10 + '0';  
  77.     if(p >9)  
  78.         add(str,index-1,1);  
  79.     return true;  
  80. }  

测试代码

view plain
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <string>  
  4. #include <cassert>  
  5. using namespace std;  
  6. string& large_mult(string str1,string str2,string& str/*输出参数*/);  
  7. bool add(string& str, int index, int num);  
  8. int main(int argc, char* argv[])  
  9. {  
  10.     printf("Please input two large number!/n");  
  11.     string str1;  
  12.     string str2;  
  13.     std::cout<<"Please input the first large number:/nstr1=";  
  14.     std::cin>> str1;  
  15.     std::cout<<"Please input the second large number::/nstr2=";  
  16.     std::cin>>str2;  
  17.       
  18.     string str; //str = str1 * str2  
  19.     large_mult(str1,str2,str);  
  20.       
  21.     std::cout<<"str=str1*str2/nstr=";  
  22.     std::cout<<str<<std::endl;  
  23.     return 0;  
  24. }