标签:
动态分配内存,由数的十进制位数决定。效率不是很高,但使用方便
(更多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