#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