标签:
动态分配内存,由数的十进制位数决定。效率不是很高,但使用方便
(更多kkke写的模版下载,在http://pan.baidu.com/s/1c26ZuOo)
#ifndef LONGINT_H
#define LONGINT_H
#include <iostream>
#include <cstring>
class longint{
int *num;
int len;
bool sign;
longint(int *new_num,int new_len,bool new_sign)
{
num=new_num;
len=new_len;
sign=new_sign;
}
public:
~longint();
longint();
longint(int a);
longint(long long a);
longint(const char *a);
longint(const std::string &a);
longint(const longint &a);
int getlen()const;
int c_int()const;
long long c_longlong()const;
friend std::ostream& operator<<(std::ostream &outs,const longint &a);
friend std::istream& operator>>(std::istream &ins,longint &a);
friend longint abs(longint a);
longint operator-()const;
longint operator=(const longint &a);
longint operator=(int a);
longint operator=(long long a);
longint operator=(const char *a);
longint operator=(const std::string &a);
longint operator+(const longint &a)const;
longint operator-(const longint &a)const;
longint operator*(const longint &a)const;
longint operator/(const longint &a)const;
longint operator%(const longint &a)const;
longint operator<<(int a)const;
longint operator>>(int a)const;
longint operator^(int k)const;
longint operator+=(const longint &a);
longint operator-=(const longint &a);
longint operator*=(const longint &a);
longint operator/=(const longint &a);
longint operator%=(const longint &a);
longint operator<<=(int a);
longint operator>>=(int a);
longint operator^=(int k);
longint operator++();
longint operator--();
longint operator++(int);
longint operator--(int);
bool operator<(const longint &a)const;
bool operator>(const longint &a)const;
bool operator<=(const longint &a)const;
bool operator>=(const longint &a)const;
bool operator!=(const longint &a)const;
bool operator==(const longint &a)const;
};
longint longint::operator%=(const longint &a)
{
return *this=*this%a;
}
longint longint::operator%(const longint &a)const
{
if(sign)return -( (-(*this)) % abs(a) );
if(a.sign)return *this%(-a);
if(*this<a)return *this;
longint b=(*this)>>(len-a.len);
while(b>=a)b-=a;
for(int i=len-a.len-1;i>=0;i--)
{
b=(b<<1)+(longint)num[i];
while(b>=a)b-=a;
}
return b;
}
longint longint::operator^=(int k)
{
*this=(*this)^k;
}
longint longint::operator^(int k)const
{
longint a=*this,b=1;
while(k)
{
if(k&1)b*=a;
a*=a;
k>>=1;
}
return b;
}
longint longint::operator/=(const longint &a)
{
return *this=*this/a;
}
longint longint::operator/(const longint &a)const
{
if(sign&&a.sign)return (-(*this))/(-a);
if(sign||a.sign)return -(abs(*this)/abs(a));
if(*this<a)return (longint)0;
int new_len=len-a.len+1;
int *new_num=new int[new_len];
longint b=(*this)>>(len-a.len);
new_num[new_len-1]=0;
while(b>=a)
{
b-=a;
new_num[new_len-1]++;
}
for(int i=new_len-2;i>=0;i--)
{
b=(b<<1)+(longint)num[i];
new_num[i]=0;
while(b>=a)
{
b-=a;
new_num[i]++;
}
}
if(!new_num[new_len-1])new_len--;
return (longint){new_num,new_len,false};
}
longint longint::operator*=(const longint &a)
{
return *this=*this*a;
}
longint longint::operator*(const longint &a)const
{
if(len==1&&num[0]==0)return *this;
if(a.len==1&&a.num[0]==0)return a;
int new_len=len+a.len;
int *new_num=new int[new_len];
for(int i=0;i<new_len;i++)new_num[i]=0;
for(int i=0;i<len;i++)
for(int j=0;j<a.len;j++)
new_num[i+j]+=num[i]*a.num[j];
for(int i=0;i<new_len;i++)
{
if(new_num[i]>=10)
{
new_num[i+1]+=new_num[i]/10;
new_num[i]%=10;
}
}
if(!new_num[new_len-1])new_len--;
return (longint){new_num,new_len,(sign==a.sign)?false:true};
}
longint abs(longint a)
{
a.sign=false;
return a;
}
longint longint::operator<<=(int a)
{
return *this=(*this)<<a;
}
longint longint::operator>>=(int a)
{
return *this=(*this)>>a;
}
longint longint::operator>>(int a)const
{
if(a>=len)return (longint)0;
int new_len=len-a;
int *new_num=new int[new_len];
for(int i=0,j=a;j<len;i++,j++)new_num[i]=num[j];
return (longint){new_num,new_len,sign};
}
longint longint::operator<<(int a)const
{
if(len==1&&num[0]==0)return *this;
int new_len=len+a;
int *new_num=new int[new_len];
for(int i=0,j=a;i<len;i++,j++)new_num[j]=num[i];
for(int i=0;i<a;i++)new_num[i]=0;
return (longint){new_num,new_len,sign};
}
longint longint::operator++()
{
return *this=*this+1;
}
longint longint::operator--()
{
return *this=*this-1;
}
longint longint::operator++(int)
{
return *this=*this+1;
}
longint longint::operator--(int)
{
return *this=*this-1;
}
longint longint::operator+=(const longint &a)
{
return *this=*this+a;
}
longint longint::operator-=(const longint &a)
{
return *this=*this-a;
}
int longint::getlen()const
{
return len;
}
longint longint::operator-(const longint &a)const
{
if(*this==a)return (longint)0;
if(sign!=a.sign)return (*this)+(-a);
if(sign)
{
if(*this>a)return (-a) - (-(*this));
return -( (-(*this)) - (-a) );
}
if(*this<a)return -(a-(*this));
int new_len=len;
int *new_num=new int[new_len];
new_num[0]=0;
for(int i=0;i<a.len;i++)
{
new_num[i]+=num[i]-a.num[i];
if(new_num[i]<0)
{
new_num[i]+=10;
new_num[i+1]=-1;
}
else if(i<len-1)new_num[i+1]=0;
}
for(int i=a.len;i<len;i++)
{
new_num[i]+=num[i];
if(new_num[i]<0)
{
new_num[i]+=10;
new_num[i+1]=-1;
}
else if(i<len-1)new_num[i+1]=0;
}
while(!new_num[new_len-1])new_len--;
return (longint){new_num,new_len,false};
}
longint longint::operator+(const longint &a)const
{
if(sign!=a.sign)return (*this)-(-a);
if(len<a.len)return a+(*this);
int new_len=len+1;
int *new_num=new int[new_len];
new_num[0]=0;
for(int i=0;i<a.len;i++)
{
new_num[i]+=num[i]+a.num[i];
if(new_num[i]>=10)
{
new_num[i]-=10;
new_num[i+1]=1;
}
else new_num[i+1]=0;
}
for(int i=a.len;i<len;i++)
{
new_num[i]+=num[i];
if(new_num[i]>=10)
{
new_num[i]-=10;
new_num[i+1]=1;
}
else new_num[i+1]=0;
}
if(!new_num[new_len-1])new_len--;
return (longint){new_num,new_len,sign};
}
bool longint::operator!=(const longint &a)const
{
if(sign!=a.sign)return true;
if(len!=a.len)return true;
for(int i=0;i<len;i++)
if(num[i]!=a.num[i])
return true;
return false;
}
bool longint::operator==(const longint &a)const
{
if(sign!=a.sign)return false;
if(len!=a.len)return false;
for(int i=0;i<len;i++)
if(num[i]!=a.num[i])
return false;
return true;
}
bool longint::operator>(const longint &a)const
{
return a<*this;
}
bool longint::operator>=(const longint &a)const
{
return !(*this<a);
}
bool longint::operator<=(const longint &a)const
{
return !(a<*this);
}
bool longint::operator<(const longint &a)const
{
if(sign&&a.sign)
{
if(len<a.len)return false;
if(len>a.len)return true;
for(int i=len-1;i>=0;i--)
{
if(num[i]<a.num[i])return false;
if(num[i]>a.num[i])return true;
}
return false;
}
if(sign)return true;
if(a.sign)return false;
if(len<a.len)return true;
if(len>a.len)return false;
for(int i=len-1;i>=0;i--)
{
if(num[i]<a.num[i])return true;
if(num[i]>a.num[i])return false;
}
return false;
}
long long longint::c_longlong()const
{
long long a=0LL;
for(int i=len-1;i>=0;i--)a=a*10LL+num[i];
return a;
}
int longint::c_int()const
{
int a=0;
for(int i=len-1;i>=0;i--)a=a*10+num[i];
return a;
}
longint longint::operator-()const
{
if(len==1&&num[0]==0)return *this;
longint a=*this;
a.sign=!sign;
return a;
}
longint longint::operator=(const std::string &a)
{
return *this=a.c_str();
}
longint longint::operator=(int a)
{
if(num)delete[] num;
if(!a)
{
num=new int[1];
num[0]=0;
len=1;
sign=false;
return *this;
}
num=new int[20];
if(a<0)
{
sign=true;
a=-a;
}
else sign=false;
len=0;
while(a)
{
num[len]=a%10;
len++;
a/=10;
}
return *this;
}
longint longint::operator=(long long a)
{
if(num)delete[] num;
if(!a)
{
num=new int[1];
num[0]=0;
len=1;
sign=false;
return *this;
}
num=new int[40];
if(a<0LL)
{
sign=true;
a=-a;
}
else sign=false;
len=0;
while(a)
{
num[len]=a%10LL;
len++;
a/=10LL;
}
return *this;
}
longint longint::operator=(const char *a)
{
if(a[0]=='-')
{
sign=true;
a++;
}
else sign=false;
len=strlen(a);
if(num)delete[] num;
num=new int[len];
for(int i=0,j=len-1;i<len;i++,j--)num[i]=a[j]-'0';
return *this;
}
longint longint::operator=(const longint &a)
{
if(num)delete[] num;
num=new int[a.len];
sign=a.sign;
len=a.len;
for(int i=0;i<len;i++)num[i]=a.num[i];
return *this;
}
longint::longint()
{
num=NULL;
}
longint::~longint()
{
if(num)delete[] num;
}
longint::longint(const char *a)
{
if(a[0]=='-')
{
sign=true;
a++;
}
else sign=false;
len=strlen(a);
num=new int[len];
for(int i=0,j=len-1;i<len;i++,j--)num[i]=a[j]-'0';
}
longint::longint(int a)
{
if(!a)
{
num=new int[1];
num[0]=0;
len=1;
sign=false;
return;
}
num=new int[20];
if(a<0)
{
sign=true;
a=-a;
}
else sign=false;
len=0;
while(a)
{
num[len]=a%10;
len++;
a/=10;
}
}
longint::longint(long long a)
{
if(!a)
{
num=new int[1];
num[0]=0;
len=1;
sign=false;
return;
}
num=new int[40];
if(a<0)
{
sign=true;
a=-a;
}
else sign=false;
len=0;
while(a)
{
num[len]=a%10;
len++;
a/=10;
}
}
longint::longint(const std::string &a)
{
num=NULL;
*this=a.c_str();
}
longint::longint(const longint &a)
{
num=new int[a.len];
sign=a.sign;
len=a.len;
for(int i=0;i<len;i++)num[i]=a.num[i];
}
std::ostream& operator<<(std::ostream &outs,const longint &a)
{
if(a.sign)outs<<'-';
for(int i=a.len-1;i>=0;i--)outs<<a.num[i];
return outs;
}
std::istream& operator>>(std::istream &ins,longint &a)
{
std::string data;
ins>>data;
a=data;
return ins;
}
#endif
上面的乘法直接用的普通O(n^2)的方法,还有一种递归实现的O(n^(1.5))的方法,不过实际情况看来并没有多大优化,而且很占空间。
思想就是每次将两个数分别分成前半部分和后半部分,两两分别相乘,递归处理,直到位数小于一定值就直接转换为int型再乘。
longint longint::operator*(const longint &a)const
{
if(len<9&&a.len<9)return c_longlong()*a.c_longlong();
if(len==1&&num[0]==0)return *this;
if(a.len==1&&a.num[0]==0)return a;
int n=std::max(len,a.len)>>1;
//XY=AC<<2n+[(A-B)(D-C)+AC+BD]<<n+BD;
longint A=(*this)>>n;
longint B=(*this)-(A<<n);
longint C=a>>n;
longint D=a-(C<<n);
longint AC=A*C;
longint BD=B*D;
return (AC<<(2*n))+( ( (A-B)*(D-C)+AC+BD ) <<n)+BD;
}
标签:
原文地址:http://blog.csdn.net/tookkke/article/details/51366490