您的位置:首页 > 编程语言 > C语言/C++

大整数类BIGN的设计与实现 C++高精度模板

2014-12-20 00:51 495 查看
首先感谢刘汝佳所著的《算法竞赛入门经典》。

众所周知,C++中储存能力最大的unsignedlonglong也是有着一个上限,如果我们想计算非常大的整数时,就不知所措了,所以,我写了一个高精度类,允许大整数的四则运算

这个类利用字符串进行输入输出,并利用数组进行储存与处理,通过模拟四则运算,可以计算很大的整数的加减乘除比大小。

支持负数,前导零,支持字符串、整型赋值,支持流输入输出

贴上我的代码:

#include<string>
#include<iostream>
#include<iosfwd>
#include<cmath>
#include<cstring>
#include<stdlib.h>
#include<stdio.h>
#include<cstring>
#defineMAX_L2005//最大长度,可以修改
usingnamespacestd;

classbign
{
public:
intlen,s[MAX_L];//数的长度,记录数组
//构造函数
bign();
bign(constchar*);
bign(int);
boolsign;//符号1正数0负数
stringtoStr()const;//转化为字符串,主要是便于输出
friendistream&operator>>(istream&,bign&);//重载输入流
friendostream&operator<<(ostream&,bign&);//重载输出流
//重载复制
bignoperator=(constchar*);
bignoperator=(int);
bignoperator=(conststring);
//重载各种比较
booloperator>(constbign&)const;
booloperator>=(constbign&)const;
booloperator<(constbign&)const;
booloperator<=(constbign&)const;
booloperator==(constbign&)const;
booloperator!=(constbign&)const;
//重载四则运算
bignoperator+(constbign&)const;
bignoperator++();
bignoperator++(int);
bignoperator+=(constbign&);
bignoperator-(constbign&)const;
bignoperator--();
bignoperator--(int);
bignoperator-=(constbign&);
bignoperator*(constbign&)const;
bignoperator*(constintnum)const;
bignoperator*=(constbign&);
bignoperator/(constbign&)const;
bignoperator/=(constbign&);
//四则运算的衍生运算
bignoperator%(constbign&)const;//取模(余数)
bignfactorial()const;//阶乘
bignSqrt()const;//整数开根(向下取整)
bignpow(constbign&)const;//次方
//一些乱乱的函数
voidclean();
~bign();
};
#definemax(a,b)a>b?a:b
#definemin(a,b)a<b?a:b

bign::bign()
{
memset(s,0,sizeof(s));
len=1;
sign=1;
}

bign::bign(constchar*num)
{
*this=num;
}

bign::bign(intnum)
{
*this=num;
}

stringbign::toStr()const
{
stringres;
res="";
for(inti=0;i<len;i++)
res=(char)(s[i]+'0')+res;
if(res=="")
res="0";
if(!sign&&res!="0")
res="-"+res;
returnres;
}

istream&operator>>(istream&in,bign&num)
{
stringstr;
in>>str;
num=str;
returnin;
}

ostream&operator<<(ostream&out,bign&num)
{
out<<num.toStr();
returnout;
}

bignbign::operator=(constchar*num)
{
memset(s,0,sizeof(s));
chara[MAX_L]="";
if(num[0]!='-')
strcpy(a,num);
else
for(inti=1;i<strlen(num);i++)
a[i-1]=num[i];
sign=!(num[0]=='-');
len=strlen(a);
for(inti=0;i<strlen(a);i++)
s[i]=a[len-i-1]-48;
return*this;
}

bignbign::operator=(intnum)
{
chartemp[MAX_L];
sprintf(temp,"%d",num);
*this=temp;
return*this;
}

bignbign::operator=(conststringnum)
{
constchar*tmp;
tmp=num.c_str();
*this=tmp;
return*this;
}

boolbign::operator<(constbign&num)const
{
if(sign^num.sign)
returnnum.sign;
if(len!=num.len)
returnlen<num.len;
for(inti=len-1;i>=0;i--)
if(s[i]!=num.s[i])
returnsign?(s[i]<num.s[i]):(!(s[i]<num.s[i]));
return!sign;
}

boolbign::operator>(constbign&num)const
{
returnnum<*this;
}

boolbign::operator<=(constbign&num)const
{
return!(*this>num);
}

boolbign::operator>=(constbign&num)const
{
return!(*this<num);
}

boolbign::operator!=(constbign&num)const
{
return*this>num||*this<num;
}

boolbign::operator==(constbign&num)const
{
return!(num!=*this);
}

bignbign::operator+(constbign&num)const
{
if(sign^num.sign)
{
bigntmp=sign?num:*this;
tmp.sign=1;
returnsign?*this-tmp:num-tmp;
}
bignresult;
result.len=0;
inttemp=0;
for(inti=0;temp||i<(max(len,num.len));i++)
{
intt=s[i]+num.s[i]+temp;
result.s[result.len++]=t%10;
temp=t/10;
}
result.sign=sign;
returnresult;
}

bignbign::operator++()
{
*this=*this+1;
return*this;
}

bignbign::operator++(int)
{
bignold=*this;
++(*this);
returnold;
}

bignbign::operator+=(constbign&num)
{
*this=*this+num;
return*this;
}

bignbign::operator-(constbign&num)const
{
bignb=num,a=*this;
if(!num.sign&&!sign)
{
b.sign=1;
a.sign=1;
returnb-a;
}
if(!b.sign)
{
b.sign=1;
returna+b;
}
if(!a.sign)
{
a.sign=1;
b=bign(0)-(a+b);
returnb;
}
if(a<b)
{
bignc=(b-a);
c.sign=false;
returnc;
}
bignresult;
result.len=0;
for(inti=0,g=0;i<a.len;i++)
{
intx=a.s[i]-g;
if(i<b.len)x-=b.s[i];
if(x>=0)g=0;
else
{
g=1;
x+=10;
}
result.s[result.len++]=x;
}
result.clean();
returnresult;
}

bignbign::operator*(constbign&num)const
{
bignresult;
result.len=len+num.len;

for(inti=0;i<len;i++)
for(intj=0;j<num.len;j++)
result.s[i+j]+=s[i]*num.s[j];

for(inti=0;i<result.len;i++)
{
result.s[i+1]+=result.s[i]/10;
result.s[i]%=10;
}
result.clean();
result.sign=!(sign^num.sign);
returnresult;
}

bignbign::operator*(constintnum)const
{
bignx=num;
bignz=*this;
returnx*z;
}
bignbign::operator*=(constbign&num)
{
*this=*this*num;
return*this;
}

bignbign::operator/(constbign&num)const
{
bignans;
ans.len=len-num.len+1;
if(ans.len<0)
{
ans.len=1;
returnans;
}

bigndivisor=*this,divid=num;
divisor.sign=divid.sign=1;
intk=ans.len-1;
intj=len-1;
while(k>=0)
{
while(divisor.s[j]==0)j--;
if(k>j)k=j;
charz[MAX_L];
memset(z,0,sizeof(z));
for(inti=j;i>=k;i--)
z[j-i]=divisor.s[i]+'0';
bigndividend=z;
if(dividend<divid){k--;continue;}
intkey=0;
while(divid*key<=dividend)key++;
key--;
ans.s[k]=key;
bigntemp=divid*key;
for(inti=0;i<k;i++)
temp=temp*10;
divisor=divisor-temp;
k--;
}
ans.clean();
ans.sign=!(sign^num.sign);
returnans;
}

bignbign::operator/=(constbign&num)
{
*this=*this/num;
return*this;
}

bignbign::operator%(constbign&num)const
{
bigna=*this,b=num;
a.sign=b.sign=1;
bignresult,temp=a/b*b;
result=a-temp;
result.sign=sign;
returnresult;
}

bignbign::pow(constbign&num)const
{
bignresult=1;
for(bigni=0;i<num;i++)
result=result*(*this);
returnresult;
}

bignbign::factorial()const
{
bignresult=1;
for(bigni=1;i<=*this;i++)
result*=i;
returnresult;
}

voidbign::clean()
{
if(len==0)len++;
while(len>1&&s[len-1]=='\0')
len--;
}

bignbign::Sqrt()const
{
if(*this<0)return-1;
if(*this<=1)return*this;
bignl=0,r=*this,mid;
while(r-l>1)
{
mid=(l+r)/2;
if(mid*mid>*this)
r=mid;
else
l=mid;
}
returnl;
}

bign::~bign()
{
}

bignnum0,num1,res;

intmain(){
num0=1,num1=2;
res=num0-num1;
cout<<res<<endl;
return0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: