#include<iostream> #include<string> #include<time.h> #include<stdlib.h> #include<sstream> using namespace std; class BigDecimal{ private: int max(int a,int b){//获取两数中的最大值 return a^((a^b) & -(a<b)); } public: string n; BigDecimal(){ n="0"; } void setString(string n){ this->n=n; } BigDecimal(string n){ this->n=n; } BigDecimal operator + (BigDecimal b){ string s,l;//s为加数,l为加数 int temp=0,i,j;//temp记录进位,i用于遍历s,j用于遍历l //判断哪个数字更长,长的给s,短的给l if(n.length()>=b.n.length()){ s=n; l=b.n; i=s.length()-1; j=b.n.length()-1; } else{ s=b.n; l=n; i=s.length()-1; j=n.length()-1; } //开始进行加法运算 while(j>=0){ s[i]=s[i]+l[j]+temp-48;//两位相加,并加上进位,减去48('0'的ASCII码) if(s[i]>'9'){//如果两位相加大于10,就减10,然后进位置1 s[i]-=10; temp=1; } else{ temp=0; } i--; j--; } //如果l遍历完后,进位仍然为1,就要消耗进位直到它为0 while(i>=0 && temp==1){ s[i]++; if(s[i]>=58){ s[i]-=10; i--; } else{ temp=0; break; } } //如果到达最高位后还有进位,则该数最前面加个'1' if(temp){ s='1'+s; } return BigDecimal(s); } BigDecimal operator - (BigDecimal b){ string S,E;//S是被减数,E是减数 /** * 由于(a1+a0)*(b1+b0)-(a1*b1+a0*b0) = a1 * b0 + a0 * b1 * 所以该减法运算不会为负数 */ S=n; E=b.n; int i=S.length()-1,j=b.n.length()-1,temp=0; // 开始进行减法运算 while(j>=0){ S[i]=S[i]+48-E[j]-temp;//两位相减,减去借位,加上48 if(S[i]<'0'){//如果不够减,加10,借位置1 S[i]+=10; temp=1; } else{ temp=0; } i--; j--; } //减完后如果借位仍然为1,消耗借位直到为0 while(i>=0 && temp){ S[i]--; if(S[i]<'0'){ S[i]+=10; temp=1; } else{ temp=0; } } i=0; //如果数字开头为0,就除去 while(S.length() > 1){ if(S[i]=='0'){ S.erase(0,1); } else{ break; } } return BigDecimal(S); } BigDecimal mul(string a,string b){ // int与int相乘 int num = atoi(a.c_str()) * atoi(b.c_str()); if(num==0)return BigDecimal(); string s; stringstream ss; ss<<num; ss>>s; return BigDecimal(s); } BigDecimal mul(string a,int n){ if(a=="0"){ return BigDecimal(); } char *k=new char[n+1]; memset(k,'0',n*sizeof(char)); k[n]='\0'; string temp; a.append(k); delete[]k; return BigDecimal(a); } void sub(int center,BigDecimal *s1,BigDecimal *s0){ if(n.length()<=center){//如果该大整数没有足够的长度被分为两半 /** * 那 a1=0 a0=n */ s0->n=n.substr(0,n.length()); } else{ /** * 否则就分成两半 */ s0->n=n.substr(n.length()-center,center); s1->n=n.substr(0,n.length()-center); } } BigDecimal operator * (BigDecimal b){ //如果数组长度小于等于4,直接调用原始乘法 if(n.length()<=4 && b.n.length()<=4){ return mul(n,b.n); } BigDecimal temp , a1 , a0 , b1 , b0 , c2 , c1 , c0; int maxBit=max(n.length() , b.n.length()); sub(maxBit/2 , &a1 , &a0); b.sub(maxBit/2 , &b1 , &b0); c2 = a1 * b1; c0 = a0 * b0; c1 = (a1 + a0) * (b1 + b0) - (c2 + c0); return mul(c2.n , maxBit/2*2) + mul(c1.n , maxBit/2) + c0; } }; int main(){ clock_t start , finish; double totaltime; srand((unsigned int)time(0)); int Bit=10;//这里修改两个大整数的位数 int pos=1; int i,j; string s,m; cout<<Bit<<" : "<<endl; do{ j=rand()%10+48; } while(j=='0'); s+=(char)j; for(i=0;i<Bit-1;i++){ j=rand()%10+48; s+=(char)j; } do{ j=rand()%10+48; } while(j=='0'); m+=(char)j; for(i=0;i<Bit-1;i++){ j=rand()%10+48; m+=(char)j; } cout<<s<<" * "<<m<<" = "<<endl; BigDecimal a(s),b(m),c; start=clock(); c=a * b; finish=clock(); cout<<c.n<<endl; totaltime=(double)(finish-start)/CLOCKS_PER_SEC; cout<<"此程序的运行时间为"<<totaltime<<"秒!"<<endl; return 0; }
如果需要更快一点的话需要自己编写一个原始乘法,然后
BigDecimal operator * (BigDecimal b){
//如果数组长度小于等于4,直接调用原始乘法
if(n.length()<=4 && b.n.length()<=4){
return mul(n,b.n);
}
BigDecimal temp , a1 , a0 , b1 , b0 , c2 , c1 , c0;
int maxBit=max(n.length() , b.n.length());
sub(maxBit/2 , &a1 , &a0);
b.sub(maxBit/2 , &b1 , &b0);
c2 = a1 * b1;
c0 = a0 * b0;
c1 = (a1 + a0) * (b1 + b0) - (c2 + c0);
return mul(c2.n , maxBit/2*2) + mul(c1.n , maxBit/2) + c0;
}
中修改
if(n.length()<=4 && b.n.length()<=4){
return mul(n,b.n);
}
中的4为600,然后改mul(n,b.n)为你的原始乘法函数mul(string,string)
大整数算法讲解与分析ppt:http://download.csdn.net/detail/u013580497/8888515
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u013580497/article/details/46834663