大整数运算包

#include<iostream>
#include<cstdio>
#include<cstring>
#include<sstream>
//#include<time.h>
#include<stdlib.h>
using namespace std;
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
const int BIGN_MAXN=5000;
const int base=10;//oct base
const int MILLER_INDEX=100;
const int BINARY_LEN=5000;
const int NUM_STR_MAXN=5000;
//s[0]:0(0) >0(1) <0(-1)  (a>b)  definit condition
class bign
{
private:
    int len,s[BIGN_MAXN];//s[0]signal .. s[1--n]digital
public:
    bign()
    {
        len=0;
        memset(s,0,sizeof(s));
    }
    ~bign() {}
    //visit private members
    int& at(int pos)
    {
        if(pos>len) return s[0];//beyond the numble length ,output signal.
        else return s[pos];
    }
    int length() const
    {
        return len;
    }
    //assignment
    bign operator =(const char x[])
    {
        len=strlen(x);
        for(int i=1; i<=len; i++) s[i]=x[len-i]-'0';
        return *this;
    }
    bign operator =(const int x)
    {
        char xx[NUM_STR_MAXN];
        sprintf(xx,"%d",x);
        *this=xx;
        return *this;
    }
    bign(const char x[])
    {
        *this=x;
    }
    bign(const int x)
    {
        *this=x;
    }
    //to-string
    string str()const
    {
        string buf="";
        for(int i=len; i>0; i--) buf+=(char)(s[i]+'0');
        if(buf=="") buf = "0";
        return buf;
    }
    //comparision
    bool operator <(const bign& x)const
    {
        if(len!=x.len) return(len<x.len);
        for(int i=len; i>0; i--) if(s[i]!=x.s[i]) return(s[i]<x.s[i]);
        return false;
    }
    bool operator >(const bign& x)const
    {
        return x<*this;
    }
    bool operator ==(const bign& x)const
    {
        return (!(*this<x)&&(!(x<*this)));
    }
    bool operator !=(const bign& x)const
    {
        return (*this<x)||(x<*this);
    }
    bool operator <=(const bign& x)const
    {
        return !(x<*this);
    }
    bool operator >=(const bign& x)const
    {
        return !(*this<x);
    }
    //calculation
    bign operator + (const bign& x) const
    {
        bign ans;
int i,cy;
        int len=max(this->len, x.len)+1;//
        for(i=1; i<=len; i++)
        {
cy=0;
if(i<=(this->len))
cy+=this->s[i];
if(i<=x.len)
cy+=x.s[i];
            ans.s[i]+=cy;
            ans.s[i+1]=ans.s[i]/base;
            ans.s[i]%=base;
        }
        if(ans.s[len]==0&&len>0) len--;
        ans.len=len;
        //取模
        return ans;
    }
    bign operator +=(const bign& x)
    {
        *this=*this+x;
        return *this;
    }
    bign operator - (const bign& x) const
    {
        bign ans=0;
        int i,cy=0;
        for(ans.len=len,i=1; i<=ans.len; i++)
        {
            ans.s[i]=s[i]-cy;
            if(i<=x.len)
                ans.s[i]-=x.s[i];
            if(ans.s[i]<0)
            {
                cy=1;
                ans.s[i]+=base;
            }
            else
            {
                cy=0;
            }
        }
        while(ans.len>0&&ans.s[ans.len]==0)
            ans.len--;
        return ans;
    }
    bign operator -=(const bign& x)
    {
        *this=*this-x;
        return *this;
    }
    bign operator *(const bign& x) const
    {
        bign ans;
        int i,j;
        int len=this->len+x.len;
        for(i=1; i<=this->len; i++)
            for(j=1; j<=x.len; j++)
                ans.s[i+j-1]+=this->s[i]*x.s[j];
for(i=1; i<=len; i++)
{
ans.s[i+1]+=ans.s[i]/base;
ans.s[i]%=base;
}
while(ans.s[len]==0&&len>0) len--;
ans.len=len;
return ans;
    }
    bign operator *=(const bign& x)
    {
        *this=*this*x;
        return *this;
    }
    bign operator /(const int x) const
    {
        bign ans;
        if(*this<x)
        {
            ans=0;
            ans.len=1;
        }
        else
        {
            int k=0,len=this->len;
            for(int i=len; i>0; i--)
            {
                ans.s[i]=(k*base+this->s[i])/x;
                k=(k*base+this->s[i])%x;
            }
            while(ans.s[len]==0&&len>0) len--;
            ans.len=len;
        }
        return ans;
    }
    bign operator /=(const int x)
    {
        *this=*this/x;
        return *this;
    }
    bign operator /( const bign& b) const
    {
        bign q,mo,bas=base,tmp,ans,mod=0;//
        if(*this<b)
        {
            ans=0;
            ans.len=1;
        }
        int i,lf,rg,mid;
        for(i=len; i>0; i--)
        {
            mod*=bas;
            tmp=s[i];
            mod+=tmp;
            for(lf=0,rg=base-1; lf<rg;)
            {
                mid=(lf+rg+1)/2;
                q=mid;
                mo=b*q;
                if(mo<=mod)
                    lf=mid;
                else
                    rg=mid-1;
            }
            ans.s[i]=lf;
            mo=lf;
            mod=mod-(b*mo);
        }
        ans.len=len;
        while(ans.len>0&&ans.s[ans.len]==0)
            ans.len--;
        return ans;
    }
    bign operator /=(const bign& x)
    {
        *this=*this/x;
        return *this;
    }
    bign operator %( const bign& b) const
    {
        bign q,mo,bas=base,tmp,ans,mod=0;
        if(*this<b)
        {
            ans=*this;
            return ans;
        }
        int i,lf,rg,mid;
        for(i=len; i>0; i--)
        {
            mod*=bas;
            tmp=s[i];
            mod+=tmp;
            for(lf=0,rg=base-1; lf<rg;)
            {
                mid=(lf+rg+1)/2;
                q=mid;
                mo=b*q;
                if(mo<=mod)
                    lf=mid;
                else
                    rg=mid-1;
            }
            ans.s[i]=lf;
            mo=lf;
            mod=mod-(b*mo);
        }
        return mod;
    }
    bign operator %=(const bign& x)
    {
        *this=*this%x;
        return *this;
    }
bign operator &(const bign& xx)const {
bign mid,ans=0,zero=0,one=1,two=2,x=xx,thi=*this;
int str[BINARY_LEN],str1[BINARY_LEN],str2[BINARY_LEN],len1=0,len2=0;
while(thi>zero){
if((thi%two)==one)
str1[++len1]=1;
else
str1[++len1]=0;
            (thi)/=two;
}
cout<<"fuck"<<endl;
while(x>zero){
if((x%two)==one)
str2[++len2]=1;
else
str2[++len2]=0;
            x/=two;
}
int i,len=min(len1,len2);
        for(i=1;i<=len;i++){
str[i]=str1[i]&str2[i];
}
mid=1;
for(i=1;i<=len;i++){
if(str[i]==1)
ans+=mid;
mid*=two;
}
return ans;
}
bign operator |(const bign& xx)const {
bign mid,ans=0,zero=0,one=1,two=2,x=xx,thi=*this;
int str[BINARY_LEN],str1[BINARY_LEN],str2[BINARY_LEN],len1=0,len2=0;
while(thi>zero){
if((thi%two)==one)
str1[++len1]=1;
else
str1[++len1]=0;
            (thi)/=two;
}
while(x>zero){
if((x%two)==one)
str2[++len2]=1;
else
str2[++len2]=0;
            x/=two;
}
int i,len=max(len1,len2);
//cout<<len<<endl;
        for(i=1;i<=len;i++){
str[i]=str1[i]|str2[i];
//cout<<str[i]<<" ";
}
mid=1;
for(i=1;i<=len;i++){
if(str[i]==1){
ans+=mid;
//  cout<<"fuck"<<endl;
}
mid*=two;
}
//ans.len=len;
return ans;
}
    bign operator ^(const bign& xx)const {
bign mid,ans=0,zero=0,one=1,two=2,x=xx,thi=*this;
int str[BINARY_LEN],str1[BINARY_LEN],str2[BINARY_LEN],len1=0,len2=0;
while(thi>zero){
if((thi%two)==one)
str1[++len1]=1;
else
str1[++len1]=0;
            (thi)/=two;
}
while(x>zero){
if((x%two)==one)
str2[++len2]=1;
else
str2[++len2]=0;
            x/=two;
}
int i,len=max(len1,len2);
//cout<<len<<endl;
        for(i=1;i<=len;i++){
            if(str1[i]==str2[i])
str[i]=0;
else
str[i]=1;
//cout<<str[i]<<" ";
}
mid=1;
for(i=1;i<=len;i++){
if(str[i]==1){
ans+=mid;
//  cout<<"fuck"<<endl;
}
mid*=two;
}
//ans.len=len;
return ans;
}
    bign operator ~()const {
bign mid,ans=0,zero=0,one=1,two=2,thi=*this;
int i,str[BINARY_LEN],len=0;
while(thi>zero){
if((thi%two)==one)
str[++len]=0;
else
str[++len]=1;
            (thi)/=two;
}
mid=1;
for(i=1;i<=len;i++){
if(str[i]==1){
ans+=mid;
//cout<<"fuck"<<endl;
}
mid*=two;
}
//ans.len=len;
return ans;
}
    bign operator ++()
    {
        bign one=1;
        *this=*this+one;
        return *this;
    }
    bign operator --()
    {
        bign c=1;
        *this=*this-c;
        return *this;
    }
bign operator <<(const bign& x) const{
int i,str[BINARY_LEN],llen=0;
bign ans=0,lift=x,thi=*this;
bign mid,zero=0,one=1,two=2;
while(thi>zero){
if((thi%two)==one)
str[++llen]=1;
else
str[++llen]=0;
            (thi)/=two;
}
while(lift>zero){
llen++;
for(i=llen;i>1;i--)
str[i]=str[i-1];
str[1]=0;
lift-=one;
}
mid=1;
for(i=1;i<=llen;i++){
if(str[i]==1){
ans+=mid;
}
mid*=two;
}
return ans;
}
bign operator <<=(const bign& x)
    {
        *this=*this<<x;
        return *this;
    }
bign operator >>(const bign& x) const{
int i,str[BINARY_LEN],rlen=0;
bign Rlen,ans=0,right=x,thi=*this;
bign mid,zero=0,one=1,two=2;
while(thi>zero){
if((thi%two)==one)
str[++rlen]=1;
else
str[++rlen]=0;
            (thi)/=two;
}
Rlen=rlen;
if(Rlen<=right)
return ans;
else{
while(right>zero){
for(i=1;i<rlen;i++)
str[i]=str[i+1];
rlen--;
right-=one;
}
mid=1;
for(i=1;i<=rlen;i++){
if(str[i]==1){
ans+=mid;
}
mid*=two;
}
return ans;
}
}
bign operator >>=(const bign& x)
    {
        *this=*this>>x;
        return *this;
    }
};
//bign index=10000000007;
//input&output
istream& operator>>(istream& in,bign& x )
{
    string s;
    in >> s;
    x=s.c_str();
    return in;
}
ostream& operator<<(ostream& out,const bign& x)
{
    return out << x.str();
}
//gcd
bign gcd(bign x,bign y)
{
    bign mid,zero=0;
    if((x==zero)||(y==zero))
        return x>y?x:y;
    for(bign t;;)
    {
        t=x%y;
        if(t<=zero){
            break;
        }
        x=y;
        y=t;
    }
    return y;
}
//lcm
bign lcm(bign x,bign y)
{
bign mid=x*y;
return mid/gcd(x,y);
}
//pow
bign pow(bign x,bign n,bign mod)
{
    bign mid,pw=1,zero=0,one=1;
x=x%mod;
    while(n>zero)
    {
//cout<<mid<<endl;
mid=n&one;
cout<<mid<<endl;
        if(mid!=zero){
            pw*=x;
pw%=mod;
}
        x*=x;
x=x%mod;
        n>>=one;
cout<<n<<endl;
    }
    return pw;
}
//Euclidean_gcd
void exc_gcd(bign a,bign b,bign& d,bign& x,bign& y)
{
    bign mid,zero=0,index=10000000007;//
    if(b<=zero)
    {
        d=a;
        x=1;
        y=0;
    }
    else
    {
        exc_gcd(b,a%b,d,y,x);
mid=(x*(a/b))%index;
        if(y>=mid)
y-=mid;
else
y=(y+index-mid)%index;
    }
}
//inverse
bign inv(bign a,bign n)
{
    bign d,x,y,one=1,neg=-1;
    exc_gcd(a,n,d,x,y);
    return d==one?(x+n)%n:neg;//
}
//miller_rabin
int witness(bign a,bign n){
bign x,d=1,mid;int i=MILLER_INDEX;
bign one=1,zero=0,two=2;
for(;i>=0;i--){
x=d;
d=(d*d)%n;
mid=i;
if((d==one)&&(x!=one)&&(x!=(n-one)))
return 1;
if(((n-one)&(mid*two))>zero)
d=(d*a)%n;
}
if(d==one)
return 0;
else
return 1;
}

int miller(bign n,int s=50){
bign a,one=1,zero=0,two=2,RAND,RAND_M;
RAND_M=(int)RAND_MAX;
if(n==two)
return 1;
if((n%two)==zero)//
return 0;
int j;//
for(j=0;j<s;j++){
RAND=(int)rand();
a=((RAND*(n-two))/RAND_M)+one;
if(witness(a,n))
return 0;
}
return 1;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值