一个大数运算类

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> #include < stdio.h >
#include
< math.h >
#include
< iostream >

using namespace std;

class decnum
{
frienddecnumpow(
const decnum & x, int n);
frienddecnumroot(
const decnum & x, int n);
frienddecnumdiv(
const decnum & x, const decnum & y,decnum & r);
frienddecnumabs(
const decnum & x);
friend
bool operator == ( const decnum & x, const decnum & y);
friend
bool operator != ( const decnum & x, const decnum & y);
friend
bool operator > ( const decnum & x, const decnum & y);
friend
bool operator < ( const decnum & x, const decnum & y);
friend
bool operator >= ( const decnum & x, const decnum & y);
friend
bool operator <= ( const decnum & x, const decnum & y);
friendostream
& operator << (ostream & os, const decnum & x);

public :
decnum():cap(
0 ),num( 0 ),sign( 0 ),val(NULL){}
decnum(
const char * v, int n)
{
int i,j,k;
val
= new char [n];
if (v[ 0 ] == ' - ' )
{
sign
= 1 ;
v
++ ;
n
-- ;
}
else
{
sign
= 0 ;
if (v[ 0 ] == ' + ' )
v
++ ;
}
for (i = 0 ;i < n && v[i] == ' 0 ' ;i ++ );
for (j = 0 ,k = n - 1 ;k >= i; -- k, ++ j)
{
if (v[k] >= ' 0 ' && v[k] <= ' 9 ' )
{
val[j]
= v[k] - ' 0 ' ;
}
else
break ;
}
num
= j;
cap
= n;
}
decnum(
const decnum & x)
{
val
= new char [x.num];
memcpy(val,x.val,x.num);
sign
= x.sign;
num
= x.num;
cap
= x.num;
}
decnum(
int x)
{
if (x == 0 )
{
cap
= num = 0 ;
val
= NULL;
return ;
}
if (x < 0 )
{
sign
= 1 ;
x
= - x;
}
else
sign
= 0 ;
char temp[ 20 ];
sprintf(temp,
" %d " ,x);
int n = strlen(temp);
num
= cap = n;
val
= new char [n];
for ( int i = 0 ;i < n;i ++ )
val[i]
= temp[n - 1 - i] - ' 0 ' ;
}
decnum(
long long x)
{
if (x == 0 )
{
cap
= num = 0 ;
val
= NULL;
return ;
}
if (x < 0 )
{
sign
= 1 ;
x
= - x;
}
else
sign
= 0 ;
char temp[ 20 ];
sprintf(temp,
" %lld " ,x);
int n = strlen(temp);
num
= cap = n;
val
= new char [n];
for ( int i = 0 ;i < n;i ++ )
val[i]
= temp[n - 1 - i] - ' 0 ' ;
}
~ decnum(){delete[]val;}

int size() const { return num;}

decnum
& operator = ( const decnum & x)
{
if ( this != & x)
{
if (cap < x.num)
{
delete[]val;
val
= new char [x.num];
cap
= x.num;
}
memcpy(val,x.val,x.num);
num
= x.num;
sign
= x.sign;
}
return * this ;
}
decnum
& operator = ( int x)
{
* this = decnum(x);
return * this ;
}
decnum
& operator = ( long long x)
{
* this = decnum(x);
return * this ;
}
decnum
& abs()
{
sign
= 0 ;
return * this ;
}
decnum
& operator += ( const decnum & x);
decnum
& operator -= ( const decnum & x);
decnum
& operator *= ( const decnum & x);
decnum
& operator /= ( const decnum & x);
decnum
& operator %= ( const decnum & x);
decnum
operator + ( const decnum & x) const ;
decnum
operator - ( const decnum & x) const ;
decnum
operator * ( const decnum & x) const ;
decnum
operator / ( const decnum & x) const ;
decnum
operator % ( const decnum & x) const ;

bool ispow( int n,decnum & r) const ;
bool ispow() const ;
private :
int cap;
int num;
int sign;
char * val;
private :
char root_1( int n);
decnum
& absadd( const decnum & x);
decnum
& abssub( const decnum & x);
bool absge( const decnum & x);
};

实现代码

ContractedBlock.gif ExpandedBlockStart.gif 大数类实现代码
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include"decnum.h"

decnum
&decnum::absadd(constdecnum&x)
{
inti,max;
charcarry=0,ch;

if(x.num==0)return*this;
if(num<x.num)
max
=x.num+1;
else
max
=num+1;
if(max>cap)
{
cap
=max;
char*newval=newchar[cap];
memcpy(newval,val,num);
memset(newval
+num,0,cap-num);
delete[]val;
val
=newval;
}
else
{
memset(val
+num,0,max-num);
}
num
=max-1;
for(i=0;i<x.num;i++)
{
ch
=val[i]+x.val[i]+carry;
if(ch>9)
{
carry
=1;
val[i]
=ch-10;
}
else
{
carry
=0;
val[i]
=ch;
}
}
for(;i<=num&&carry==1;i++)
{
ch
=val[i]+1;
if(ch>9)
{
carry
=1;
val[i]
=ch-10;
}
else
{
carry
=0;
val[i]
=ch;
}
}
if(i>num)num=i;
return*this;
}

decnum
&decnum::abssub(constdecnum&x)
{
if(x.num==0)return*this;
inti;
charcarry=0,ch;
for(i=0;i<x.num;i++)
{
ch
=val[i]-x.val[i]-carry;
if(ch<0)
{
carry
=1;
val[i]
=ch+10;
}
else
{
carry
=0;
val[i]
=ch;
}
}
for(;i<num&&carry==1;i++)
{
ch
=val[i]-1;
if(ch<0)
{
carry
=1;
val[i]
=ch+10;
}
else
{
carry
=0;
val[i]
=ch;
}
}
for(i=num;i>0&&val[i-1]==0;i--);
num
=i;
return*this;
}

booldecnum::absge(constdecnum&x)
{
if(num>x.num)returntrue;
if(num<x.num)returnfalse;
for(inti=num-1;i>=0;i--)
{
if(val[i]>x.val[i])
returntrue;
elseif(val[i]<x.val[i])
returnfalse;
}
returntrue;
}

decnum
&decnum::operator+=(constdecnum&x)
{
if(x.sign==sign)
returnabsadd(x);
elseif(absge(x))
returnabssub(x);
else
{
decnumtmp(
*this);
*this=x;
returnabssub(tmp);
}
}

decnum
&decnum::operator-=(constdecnum&x)
{
if(x.sign!=sign)
returnabsadd(x);
elseif(absge(x))
returnabssub(x);
else
{
decnumtmp(
*this);
*this=x;
returnabssub(tmp);
}
}

decnum
&decnum::operator*=(constdecnum&x)
{
if(num==0)return*this;
if(x.num==0)
{
num
=0;
return*this;
}
if(sign==x.sign)
sign
=0;
else
sign
=1;
intmul,i,n,newcap,max;
charch,carry;
char*newval=newchar[num+x.num];
newcap
=num+x.num;
memset(newval,
0,num+x.num);

decnuma,b;
char*ptr;
for(i=0;i<num&&val[i]==0;i++);
intna=i;
a.val
=val+i;
a.num
=num-i;
for(i=0;i<num&&x.val[i]==0;i++);
intnb=i;
b.val
=x.val+i;
b.num
=x.num-i;
ptr
=newval+na+nb;

for(n=0;n<=a.num+b.num-2;n++)
{
mul
=0;
if(n>b.num-1)
i
=n-b.num+1;
else
i
=0;
max
=n<a.num-1?n:a.num-1;
for(;i<=max;i++)
mul
+=a.val[i]*b.val[n-i];
carry
=0;
for(i=n;mul>0||carry>0;mul/=10,i++)
{
ch
=ptr[i]+mul%10+carry;
if(ch>9)
{
carry
=1;
ptr[i]
=ch-10;
}
else
{
carry
=0;
ptr[i]
=ch;
}
}
}
for(i=a.num+b.num;i>0&&ptr[i-1]==0;i--);
num
=i+na+nb;
if(cap>=num)
{
memcpy(val,newval,num);
delete[]newval;
}
else
{
cap
=newcap;
delete[]val;
val
=newval;
}
a.val
=b.val=NULL;
return*this;
}

decnum
&decnum::operator/=(constdecnum&x)
{
charch,carry,fac;
decnumtmp;
inti;
if(x.num==0)return*this;
if(num<x.num)
{
num
=0;
return*this;
}
if(sign==x.sign)
sign
=0;
else
sign
=1;
char*newval=newchar[num-x.num+1];
memset(newval,
0,num-x.num+1);
carry
=0;
fac
=x.val[x.num-1]+1;
tmp.val
=val+num-x.num+1;
tmp.cap
=tmp.num=x.num-1;
for(i=num-1;i>=x.num-1;i--)
{
tmp.val
--;
tmp.num
++;
ch
=(carry*10+val[i])/fac;
tmp
-=x*ch;
while(tmp>=x)
{
tmp
-=x;
ch
++;
}
newval[i
-x.num+1]=ch;
carry
=val[i];
}
tmp.val
=NULL;
for(i=num-x.num+1;i>0&&newval[i-1]==0;i--);
num
=i;
delete[]val;
val
=newval;
return*this;
}

decnum
&decnum::operator%=(constdecnum&x)
{
charch,carry,fac;
decnumtmp;
inti;
if(x.num==0)return*this;
if(num<x.num)return*this;

carry
=0;
fac
=x.val[x.num-1]+1;
tmp.val
=val+num-x.num+1;
tmp.num
=x.num-1;
for(i=num-1;i>=x.num-1;i--)
{
tmp.val
--;
tmp.num
++;
ch
=(carry*10+val[i])/fac;
tmp
-=x*ch;
while(tmp>=x)
{
tmp
-=x;
ch
++;
}
carry
=val[i];
}
tmp.val
=NULL;
num
=tmp.num;
return*this;
}

decnumdecnum::
operator+(constdecnum&x)const
{
decnumtmp
=*this;
returntmp+=x;
}

decnumdecnum::
operator-(constdecnum&x)const
{
decnumtmp
=*this;
returntmp-=x;
}

decnumdecnum::
operator*(constdecnum&x)const
{
decnumtmp
=*this;
returntmp*=x;
}

decnumdecnum::
operator/(constdecnum&x)const
{
decnumtmp
=*this;
returntmp/=x;
}

decnumdecnum::
operator%(constdecnum&x)const
{
decnumtmp
=*this;
returntmp%=x;
}

decnumabs(
constdecnum&x)
{
decnumtmp(x);
tmp.sign
=0;
returntmp;
}

decnumpow(
constdecnum&x,intn)
{
decnumtmp(
1),fac(x);
for(;n>0;n>>=1)
{
if(n&0x01)
tmp
*=fac;
fac
*=fac;
}
returntmp;
}

chardecnum::root_1(intn)
{
charr=(int)(pow(1+val[num-1],1.0/n)*pow(10,(num-1.0)/n));
for(;r>0&&pow(decnum(r),n)>*this;r--);
returnr;
}

booldecnum::ispow(intn,decnum&r)const
{
if(num==0)
{
r.num
=0;
returntrue;
}
if(sign==1&&(n&1==0))
{
r.num
=0;
returnfalse;
}
decnumtmp,p;
r.cap
=r.num=(num+n-1)/n;
r.val
=newchar[r.num];
r.sign
=sign;
memset(r.val,
0,r.num);
tmp.val
=val+(r.num-1)*n;
tmp.num
=num-(r.num-1)*n;
r.val[r.num
-1]=tmp.root_1(n);

tmp.val
=newchar[r.num+1];
tmp.cap
=r.num+1;
intv;
p
=pow(r,n);
if(p==*this)returntrue;
for(inti=r.num-2;i>=0;i--)
{
memset(tmp.val,
0,i+1);
tmp.val[i]
=1;
tmp.num
=i+1;
tmp
+=r;
p
=(*this-p)/(pow(tmp,n)-p);
if(p.num>1)
v
=9;
elseif(p.num>0)
v
=p.val[0];
else
v
=0;
for(;v>=0;v--)
{
r.val[i]
=v;
p
=pow(r,n);
if(p==*this)
returntrue;
if(p<*this)
break;
}
}
returnfalse;
}

booldecnum::ispow()const
{
decnumr,dec2(
"2",1);
if(ispow(2,r))returntrue;
for(intn=3;r>dec2;n+=2)
{
if(ispow(n,r))returntrue;
}
returnfalse;
}

decnumroot(
constdecnum&x,intn)
{
decnumr;
x.ispow(n,r);
returnr;
}

decnumdiv(
constdecnum&x,constdecnum&y,decnum&r)
{
charch,carry,fac;
decnumd
=x,tmp;
inti;
if(y.num==0)returnx;
if(d.num<y.num)
{
r
=x;
d
=0;
returnd;
}
char*newval=newchar[d.num-y.num+1];
memset(newval,
0,d.num-y.num+1);
carry
=0;
fac
=y.val[y.num-1]+1;
tmp.val
=d.val+d.num-y.num+1;
tmp.num
=y.num-1;
for(i=d.num-1;i>=y.num-1;i--)
{
tmp.val
--;
tmp.num
++;
ch
=(carry*10+d.val[i])/fac;
tmp
-=y*ch;
while(tmp>=y)
{
tmp
-=y;
ch
++;
}
newval[i
-y.num+1]=ch;
carry
=d.val[i];
}
r
=tmp;
tmp.val
=NULL;
for(i=d.num-y.num+1;i>0&&newval[i-1]==0;i--);
d.num
=i;
delete[]d.val;
d.val
=newval;
returnd;
}

booloperator==(constdecnum&x,constdecnum&y)
{
if(x.sign!=y.sign)returnfalse;
if(x.num!=y.num)returnfalse;
for(inti=0;i<x.num;i++)
{
if(x.val[i]!=y.val[i])
returnfalse;
}
returntrue;
}

booloperator!=(constdecnum&x,constdecnum&y)
{
return!(x==y);
}

booloperator>(constdecnum&x,constdecnum&y)
{
if(x.sign>y.sign)returnfalse;
if(x.sign<y.sign)returntrue;
boolretval=(x.sign==0);
if(x.num>y.num)returnretval;
if(x.num<y.num)return!retval;
for(inti=x.num-1;i>=0;i--)
{
if(x.val[i]>y.val[i])
returnretval;
elseif(x.val[i]<y.val[i])
return!retval;
}
returnfalse;
}

booloperator<(constdecnum&x,constdecnum&y)
{
returny>x;
}

booloperator>=(constdecnum&x,constdecnum&y)
{
if(x.sign>y.sign)returnfalse;
if(x.sign<y.sign)returntrue;
boolretval=(x.sign==0);
if(x.num>y.num)returnretval;
if(x.num<y.num)return!retval;
for(inti=x.num-1;i>=0;i--)
{
if(x.val[i]>y.val[i])
returnretval;
elseif(x.val[i]<y.val[i])
return!retval;
}
returntrue;
}

booloperator<=(constdecnum&x,constdecnum&y)
{
returny>=x;
}

ostream
&operator<<(ostream&os,constdecnum&x)
{
if(x.size()==0)
os
<<0;
else
{
if(x.sign==1)
os
<<"-";
for(inti=x.size()-1;i>=0;i--)
os
<<(int)x.val[i];
}
returnos;
}

测试代码:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> #include < iostream >
#include
< string >
using namespace std;
#include
" decnum.h "

int main()
{
decnumx,y,r;
string line;
size_tn
= 0 ;
cout
<< " inputx: " << endl;
getline(cin,line);
x
= decnum(line.c_str(),line.length());
cout
<< " inputy: " << endl;
getline(cin,line);
y
= decnum(line.c_str(),line.length());
cout
<< " x= " << x << endl;
cout
<< " y= " << y << endl;
cout
<< " x*y= " << x * y << endl;
cout
<< " x/y= " << x / y << endl;
cout
<< " x%y= " << x % y << endl;
cout
<< " div(x,y)= " << div(x,y,r) << endl;
cout
<< " mod(x,y)= " << r << endl;
cout
<< " y^2= " << pow(y, 2 ) << endl;
cout
<< " x^1/2= " << root(x, 2 ) << endl;
cout
<< " xispow= " << x.ispow() << endl;
system(
" pause " );
return 0 ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.问题描述 密码学分为两密码:对称密码和非对称密码。对称密码主要用于数据的加/解密,而非对称密码则主要用于认证、数字签名等场合。非对称密码在加密和解密时,是把加密的数据当作一个大的正整数来处理,这样就涉及到大整数的加、减、乘、除和指数运算等,同时,还需要对大整数进行输出。请采用相应的数据结构实现大整数的加、减、乘、除和指数运算,以及大整数的输入和输出。 2.实验基本要求 要求采用链表来实现大整数的存储和运算,不允许使用标准模板的链表(list)和函数。同时要求可以从键盘输入大整数,也可以文件输入大整数,大整数可以输出至显示器,也可以输出至文件。大整数的存储、运算和显示,可以同时支持二进制和十进制,但至少要支持十进制。大整数输出显示时,必须能清楚地表达出整数的位数。测试时,各种情况都需要测试,并附上测试截图;要求测试例子要比较详尽,各种极限情况也要考虑到,测试的输出信息要详细易懂,表明各个功能的执行正确; 1. 要求大整数的长度可以不受限制,即大整数的十进制位数不受限制,可以为十几位的整数,也可以为500多位的整数,甚至更长;大整数的运算和显示时,只需要考虑正的大整数。如果可能的话,请以秒为单位显示每次大整数运算的时间; 2. 要求采用的设计思路,不允许出现以外的函数定义,但允许友元函数。主函数中只能出现的成员函数的调用,不允许出现对其它函数的调用。 3. 要求采用多文件方式:.h文件存储的声明,.cpp文件存储的实现,主函数main存储在另外一个单独的cpp文件中。如果采用模板,则的声明和实现都放在.h文件中。 4. 不强制要求采用模板,也不要求采用可视化窗口;要求源程序中有相应注释; 5. 要求采用Visual C++ 6.0及以上版本进行调试; 3.实现提示 1. 大整数的加减运算可以分解为普通整数的运算来实现;而大整数的乘、除和指数运算,可以分解为大整数的加减运算。 2. 大整数的加、减、乘、除和指数运算,一般是在求两大整数在取余操作下的加、减、乘、除和指数运算,即分别求 (a +b) mod n, (a - b) mod n, (a * b) mod n, (a / b) mod n 和(a ^ b) mod n。其中a ^ b 是求a的b次方,而n称之为模数。说明:取余操作(即mod操作)是计算相除之后所得的余数,不同于除法运算的是,取余操作得到的是余数,而不是除数。如7 mod 5 = 2。模数n的设定,可以为2m 或10m,m允许每次计算时从键盘输入。模数n的取值一般为2512(相当于十进制150位左右),21024(相当于十进制200~300位),22048(相当于十进制300~500位)。为了测试,模数n也可以为2256, 2128等值。 3. 需要设计主要有:链表和大整数。链表用于处理链表的相关操作,包括缺省构造函数、拷贝构造函数、赋值函数、析构函数、链表的创建、插入、删除和显示等;而大整数则用于处理大整数的各种运算和显示等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值