关于高精度运算bign类的实现

对与基本的运算由于数据类型存储空间有限导致运算结果较大时容易计算溢出,这里通过引入数字数组定义适用于高精度运算的bign类实现大数运算的精确表示,包括常见的赋值/比较/四则运算:

#include<string>
#include<iostream>
#include<cmath>
#include<cstring>
#define MAX_L 2005
using namespace std;
class bign{
    public:
	int len;
	int s[MAX_L];
	bign();
	bign(const char*);
	bign(int);
	bool sign;//1 is positive
	string to_str()const;
	friend istream& operator>>(istream &,bign &);
	friend ostream& operator<<(ostream &,bign &);
	//重载复制
	bign operator=(const char *);
	bign operator=(int);
	bign operator=(const string);
	//重载比较
	bool operator>(const bign &)const;
	bool operator>=(const bign &)const;
	bool operator<(const bign &)const;
	bool operator<=(const bign &)const;
	bool operator==(const bign &)const;
	bool operator!=(const bign &)const;
	//四则运算重载
	bign operator+(const bign &)const;
	bign operator++();
	bign operator++(int);
	bign operator+=(const bign&);
	bign operator-(const bign &)const;
	bign operator--();
	bign operator--(int);
	bign operator-=(const bign&);
        bign operator*(const bign&)const; 
	bign operator*(const int num)const;
	bign operator*=(const bign&);
	bign operator/(const bign&)const;
	bign operator/=(const bign&);
	//四则扩展运算符重载
	bign operator%(const bign&)const;

	//剩下的函数
	void dis(){if(sign==0)cout<<"-";
	           for(int i=0;i<len;i++)std::cout<<s[len-i-1];
		   std::cout<<std::endl;
	           }
};
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
bign::bign(){memset(s,0,sizeof(s));len=1;sign=1;}
bign::bign(const char *num){*this=num;}
bign::bign(int num){*this=num;}
string bign::to_str()const{
string res;
res="";//初始化
int i;
for(i=0;i<len;i++)
    res=(char)(s[i]+'0')+res;
if(res=="")return "0";
if(sign!=1&&res!="")res='-'+res;
return res;
}
istream &operator>>(istream &in,bign&num){
string res;
in>>res;
num=res;
return in;
}
ostream &operator<<(ostream &out,bign&num){
out<<num.to_str();
return out;
}
bign bign::operator=(const char*num){
memset(s,0,sizeof(s));//s初始化
char tmp[MAX_L]="";
if(num[0]!='-')strcpy(tmp,num);
else {for(int i=1;i<strlen(num);i++)tmp[i-1]=num[i];}
len=strlen(tmp);sign=!(num[0]=='-');
for(int i=0;i<len;i++)
    s[i]=tmp[len-i-1]-'0';
    int i=len-1;
    while(s[i]==0&&i>0){i--;len--;}
return *this;
}
bign bign::operator=(int num){
//也可以采用sprintf
int i=0;
if(num<0){sign=0;num=-1*num;}
else sign=1;
int a=num;int tmp;
while(a>0){tmp=a;a=a/10;s[i++]=tmp%10;}
len=i;
    i=len-1;
    while(s[i]==0&&i>0){i--;len--;}
return *this;
}
bign bign::operator=(const string num){
const char *tmp;
tmp=num.c_str();
*this=tmp;
return *this;
}
bool bign::operator>(const bign &obj)const{
if(sign^obj.sign)return (*this).sign;//不同符号
if(len!=obj.len)return sign?(len>obj.len):(!(len>obj.len));//相同符号不同长度
for(int i=len-1;i>=0;i--)
    if(s[i]!=obj.s[i])
	return sign?(s[i]>obj.s[i]):(!(s[i]>obj.s[i]));
return 0;
}
bool bign::operator<(const bign &obj)const{
return (obj>*this);
}
bool bign::operator>=(const bign &obj)const{
return !(*this<obj);
}
bool bign::operator<=(const bign &obj)const{
return ~(*this>obj);
}
bool bign::operator!=(const bign &obj)const{
return (*this>obj)||(*this<obj);
}
bool bign::operator==(const bign &obj)const{
return !(*this!=obj);
}
bign bign::operator+(const bign&num)const{
bign res;
res.len=0;
int i;
if(sign^num.sign){
    bign tmp=sign?num:*this;//找出减数
    tmp.sign=1;//加法变成减法
    res=sign?*this-tmp:num-tmp;
                 }//两者不同符号
else{
    int add=0;
    for(i=0;add||i<(max(len,num.len));i++)
    {
	int t=s[i]+num.s[i]+add;
        res.s[res.len++]=t%10;add=t/10;
    }
    res.sign=sign;
    int i=res.len-1;
    while(res.s[i]==0&&i>0){i--;res.len--;}
    }//两者同号
return res;
}
bign bign::operator++(){
*this=*this+1;
return *this;
}
bign bign::operator++(int){
bign tmp=*this;
++(*this);
return tmp;
}
bign bign::operator+=(const bign&num){
*this=*this+num;
return *this;
}
bign bign::operator-(const bign&num)const{
bign a=*this;//被减数
bign b=num;//减数
bign res;res.len=0;
if(!sign&&!num.sign){
    a.sign=1;b.sign=1;
    res=b-a;
                 }//两数都是负数
else if(!num.sign){b.sign=1;res=a+b;}//减数是负数
else if(!sign){a.sign=1;res=bign(0)-(a+b);}//被减数是负数
else{
    if(a<b){res=b-a;res.sign=0;}//被减数小
    else{int add=0;
        for(int i=0;i<a.len;i++)
	{int t=a.s[i]-add;
	 if(i<b.len)t=t-b.s[i];
	 if(t>=0)add=0;
	 else{add=1;t=t+10;}//退位
	 res.s[res.len++]=t;
	}
        }//被减数大
    }//两者都是正数
    int i=res.len-1;
    while(res.s[i]==0&&i>0){i--;res.len--;}
return res;
}
bign bign::operator--(){
*this=*this-1;
return *this;
}
bign bign::operator--(int){
bign tmp=*this;
--(*this);
return tmp;
}
bign bign::operator-=(const bign&num){
*this=*this-num;
return *this;
}
bign bign::operator*(const bign&num)const{
bign res;
res.len=len+num.len-1;
int i,j;
for(i=0;i<len;i++)
    for(j=0;j<num.len;j++)
    {
    res.s[i+j]+=s[i]*num.s[j];
    }
int add=0;
for(i=0;i<res.len;i++)
{int t=res.s[i]+add;res.s[i]=t%10;add=t/10;}
res.sign=!(sign^num.sign);
     i=res.len-1;
    while(res.s[i]==0&&i>0){i--;res.len--;}
return res;
}
bign bign::operator*=(const bign&num){
*this=*this*num;
return *this;
}
bign bign::operator*(const int num)const{
bign x=num;
return *this*x;
}
bign bign::operator/(const bign&num)const{
bign res;
res.len=len-num.len+1;
if(res.len<0){res.len=1;return res;}//被除数小
bign a=*this;//被除数
bign b=num;//除数
a.sign=b.sign=1;
int i;
bign tmp=0;
for(i=len-1;i>=0;i--)
{tmp=tmp*10;
tmp.s[0]=s[i];//每次循环就是一次移位
while(tmp>=b){tmp-=b;res.s[i]++;}
}
res.sign=!(sign^num.sign);
 i=res.len-1;
    while(res.s[i]==0&&i>0){i--;res.len--;}
return res;
}
bign bign::operator/=(const bign&num){
*this=*this/num;
return *this;
}
bign bign::operator%(const bign&num)const{
bign res=*this/num;
res=*this-res*num;
return res;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值