zoukankan      html  css  js  c++  java
  • 压位高精度模板

    不走程序,直接上板子。
    第一个板子压四位,支持带符号的加减乘。
    第二个板子压九位,支持不带符号的四则运算和取模。
    都封装了。


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    struct intX
    {
    	static const int M=600;
    	int xb[M+5];
    	intX& operator=(const char* c)
    	{
    		memset(xb,0,sizeof(xb));
    		int n=strlen(c),j=1,k=1;
    		for(int i=1;i<n;i++,k*=10)
    		{
    			if(k==10000) j++,k=1;
    			xb[j]+=k*(c[n-i]-'0');
    		}
    		xb[0]=j,xb[M]=c[0]-'0';
    		return *this;
    	}
    	intX& operator=(int a)
    	{
    		char s[25];
    		sprintf(s+1,"%d",a);
    		if(a<0) s[0]='1'; else s[0]='0';
    		return *this=s;
    	}
    	intX() {memset(xb,0,sizeof(xb)); xb[0]=1;}
    	intX(int n) {*this=n;}
    	bool operator>(const intX &b) const
    	{
    		if(xb[M]!=b.xb[M]) return xb[M]<b.xb[M];
    		if(xb[0]!=b.xb[0]) return xb[M]?xb[0]<b.xb[0]:xb[0]>b.xb[0];
    		for(int i=xb[0];i>0;i--)
    			if(xb[i]!=b.xb[i]) return xb[M]?xb[i]<b.xb[i]:xb[i]>b.xb[i];
    		return false;
    	}
    	bool operator<(const intX &b) const {return b>*this;}
    	bool operator<=(const intX &b) const {return !(*this>b);}
    	bool operator>=(const intX &b) const {return !(b>*this);}
    	bool operator!=(const intX &b) const {return b>*this||*this>b;}
    	bool operator==(const intX &b) const {return !(b>*this)&&!(*this>b);}
    	intX operator+(const intX &b) const
    	{
    		intX c,d=b,e=*this;
    		if(xb[M]^b.xb[M])
    		{
    			e.xb[M]=d.xb[M]=0;
    			c=e>d?e-d:d-e;
    			if((e>d&&xb[M]) || (e<d&&b.xb[M])) c.xb[M]=1;
    			return c;
    		}
    		c.xb[0]=max(xb[0],b.xb[0]), c.xb[M]=xb[M];
    		for(int i=1;i<=c.xb[0];i++)
    		{
    			c.xb[i]+=xb[i]+b.xb[i];
    			if(c.xb[i]>9999) c.xb[i]-=10000, c.xb[i+1]++;
    		}
    		if(c.xb[c.xb[0]+1]>0) c.xb[0]++;
    		return c;
    	}
    	intX operator-(const intX &b) const
    	{
    		intX c,d=b,e=*this;
    		if(e<0 && d<0) {d.xb[M]=e.xb[M]=0; return d-e;}
    		else if(d<0) {d.xb[M]=0; return d+e;}
    		else if(e<0) {d.xb[M]=1; return d+e;}
    		else if(e<d) {c=d-e; c.xb[M]=1; return c;}
    		c.xb[0]=xb[0];
    		for(int i=1;i<=c.xb[0];i++)
    		{
    			c.xb[i]+=xb[i]-b.xb[i];
    			if(c.xb[i]<0) c.xb[i]+=10000, c.xb[i+1]--;
    		}
    		while(!c.xb[c.xb[0]]&&c.xb[0]>1) c.xb[0]--;
    		return c;
    	}
    	intX& operator+=(const intX &b) {return *this=*this+b;}
    	intX& operator-=(const intX &b) {return *this=*this-b;}
    	intX operator*(const intX &b) const
    	{
    		intX c;
    		c.xb[0]=xb[0]+b.xb[0]+1;
    		for(int i=1;i<=xb[0];i++)
    			for(int j=1;j<=b.xb[0];j++)
    				c.xb[i+j-1]+=xb[i]*b.xb[j],
    				c.xb[i+j]+=c.xb[i+j-1]/10000,
    				c.xb[i+j-1]%=10000;
    		while(!c.xb[c.xb[0]] && c.xb[0]>1) c.xb[0]--;
    		if(*this!=0 && b!=0) c.xb[M]=xb[M]^b.xb[M];
    		return c;
    	}
    	intX operator*=(const intX &b) {return *this=*this*b;}
    	void readX(intX &b)
    	{
    		char s[2*M]; scanf("%s",s+1);
    		if(s[1]=='-') s[1]='0',s[0]='1'; else s[0]='0';
    		b=s;
    	}
    	void writeX()
        {
    		if(xb[M]) printf("-");
        	printf("%d",xb[xb[0]]);
        	for(int i=xb[0]-1;i>0;i--)
           		printf("%04d",xb[i]);
    	}
    };
    int main()
    {
        intX a,b;
    	a.readX(a),b.readX(b);
    	(a+b).writeX();
        return 0;
    }
    

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int LEN=10000+1,BIT=9;
    struct intX 
    {
        static const int MOD=1000000000;
        long long s[LEN];
        bool flag;
        intX() {memset(s,0,sizeof(s)); s[0]=flag=1;}
        intX& operator=(const char *num)
    	{
            int l=strlen(num);
            memset(s,0,sizeof(s));
            for(int i=l-1;i>=0;i-=BIT)
    		{
                ++s[0];
                long long w=1;
                for(int j=i;j>i-BIT && j>=0;j--) 
                    s[s[0]]+=(num[j]^48)*w, w*=10;
            }
            return *this;
        }
        intX& operator=(int num) 
    	{
            char a[LEN];
            sprintf(a,"%d",num);
            return *this=a;
        }
        intX(int n) {*this = n;}
        intX(const char *n) {*this = n;}
    	bool operator>(const intX &a) const
    	{
            if(s[0]!=a.s[0]) return s[0]>a.s[0];
            int up=max(s[0],a.s[0]);
            for(int i=0;i<up;i++)
                if(s[up-i]!=a.s[up-i]) return s[up-i]>a.s[up-i];
            return false;
        }
    	bool operator<(const intX &a) const {return a>*this;}
    	bool operator<=(const intX &a) const {return !(*this>a);}
    	bool operator>=(const intX &a) const {return !(a>*this);}
    	bool operator!=(const intX &a) const {return a>*this||*this>a;}
    	bool operator==(const intX &a) const {return !(a>*this)&&!(*this>a);}
        intX operator+(const intX &a) const
    	{
            intX c;
            int x=0;
            c.s[0]=max(a.s[0],s[0])+1;
            for(int i=1;i<=c.s[0];i++) 
                c.s[i]=a.s[i]+s[i]+x,
                x=c.s[i]/MOD,
                c.s[i]%=MOD;
            while(c.s[c.s[0]]==0 && c.s[0]>1) c.s[0]--;
            return c;
        }
        intX& operator+=(const intX &a) {return *this=*this+a;}
        intX operator-(const intX &a) const
    	{
            intX c;
            c.s[0]=max(a.s[0],s[0])+1;
            if(*this<a) c.flag=false;
            for(int i=1;i<=c.s[0];i++) 
    		{
                if(c.flag) c.s[i]+=s[i]-a.s[i];
                else c.s[i]+=a.s[i]-s[i];
                if(c.s[i]<0) c.s[i]+=MOD, c.s[i+1]--;
            }
            while(c.s[c.s[0]]==0 && c.s[0]>1) c.s[0]--;
            return c;
        }
        intX& operator-=(const intX &a) {return *this=*this-a;}
        intX operator*(const intX &a) const
    	{
            intX c;
            c.s[0]=s[0]+a.s[0];
            for(int i=1;i<=s[0];i++)
    		{
                int x=0;
                for(int j=1;j<=a.s[0];j++) 
                    c.s[i+j-1]+=s[i]*a.s[j]+x,
                    x=c.s[i+j-1]/MOD,
                    c.s[i+j-1]%=MOD;
                c.s[i+a.s[0]]=x;
            }
            while(c.s[c.s[0]]>0) c.s[0]++;
            while(c.s[c.s[0]]==0 && c.s[0]>1) c.s[0]--;
            return c;
        }
        intX& operator*=(const intX &a) {return *this=*this*a;}
        intX operator<<(const int &num)
    	{
            s[0]++;
            for(int i=1;i<=s[0];i++) 
    		{
    			s[i]<<=num;
                if(s[i-1]>=MOD) s[i-1]-=MOD, ++s[i];
            }
            while(s[s[0]]==0 && s[0]>1) s[0]--;
            return *this;
        }
        intX operator>>(const int &num) 
    	{
            for(int i=s[0];i>=1;i--) 
    		{
                if((s[i]&1) && i>1) s[i-1]+=MOD;
                s[i]>>=num;
            }
            while(s[s[0]]==0 && s[0]>1) s[0]--;
            return *this;
        }
        intX operator/(const intX &k) const
    	{
            intX c=*this,tmp,lt,a;
            a=k;
            tmp.s[1]=1;
            while(c>=a) a=a<<1,tmp=tmp<<1;
            while(tmp.s[0]>1 || tmp.s[1]) 
    		{
                if(c>=a) c-=a, lt+=tmp;
                a=a>>1, tmp=tmp>>1;
            }
            c=lt;
            while(c.s[c.s[0]]==0 && c.s[0]>1) c.s[0]--;
            if(c.s[0]<1) c.s[c.s[0]=1]=0;
            return c;
        }
        intX& operator/=(const intX &a) {return *this=*this/a;}
        intX operator%(const intX &a) const {return *this-*this/a*a;}
        intX& operator%=(const intX &a) {return *this=*this%a;}
    };
    ostream& operator<<(ostream &out,const intX &a) 
    {
        if(!a.flag) putchar('-');
        printf("%lld",a.s[a.s[0]]);
        for(int i=a.s[0]-1;i>=1;i--)
            printf("%0*lld",BIT,a.s[i]);
        return out;
    }
    istream& operator>>(istream &in,intX &a) 
    {
        char str[LEN];
        scanf("%s",str);
        a=str;
        return in;
    }
    

    UPD:距离第一次写就这篇文章已有5个月,在此期间遇到了很多需要高精的题,才发现之前的模板有很多的缺陷,压位和多种运算固然不错,但独立性太差,码量过多与基于自损相减的除法运算复杂度过高还是硬伤,于是这次更新了新的Wint
    新的写法基于vector实现,码量--,除法换成了高精除低精,并且各运算相对独立,在实际应用中表现更好。

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    struct Wint:vector<int>
    {
        Wint(int n=0) {push_back(n);check();}
        Wint& check()
        {
            while(!empty()&&!back()) pop_back();
            if(empty()) return *this;
            for(int i=1;i<size();++i)
                (*this)[i]+=(*this)[i-1]/10,
                (*this)[i-1]%=10;
            while(back()>=10)
            {
                push_back(back()/10);
                (*this)[size()-2]%=10;
            }
            return *this;
        }
    };
    bool operator!=(const Wint &a,const Wint &b)
    {
        if(a.size()!=b.size()) return 1;
        for(int i=a.size()-1;i>=0;--i)
            if(a[i]!=b[i]) return 1;
        return 0;
    }
    bool operator==(const Wint &a,const Wint &b) {return !(a!=b);}
    bool operator<(const Wint &a,const Wint &b)
    {
        if(a.size()!=b.size()) return a.size()<b.size();
        for(int i=a.size()-1;i>=0;--i)
            if(a[i]!=b[i]) return a[i]<b[i];
        return 0;
    }
    bool operator>(const Wint &a,const Wint &b) {return b<a;}
    bool operator<=(const Wint &a,const Wint &b) {return !(a>b);}
    bool operator>=(const Wint &a,const Wint &b) {return !(a<b);}
    Wint& operator+=(Wint &a,const Wint &b)
    {
        if(a.size()<b.size()) a.resize(b.size());
        for(int i=0;i<b.size();++i) a[i]+=b[i];
        return a.check();
    }
    Wint operator+(Wint a,const Wint &b) {return a+=b;}
    Wint& operator-=(Wint &a,Wint b)
    {
        if(a<b) swap(a,b);
        for(int i=0;i<b.size();a[i]-=b[i],++i)
            if(a[i]<b[i])
            {
                int j=i+1;
                while(!a[j]) ++j;
                while(j>i) --a[j],a[--j]+=10;
            }
        return a.check();
    }
    Wint operator-(Wint a,const Wint &b) {return a-=b;}
    Wint operator*(const Wint &a,const Wint &b)
    {
        Wint n;
        n.assign(a.size()+b.size()-1,0);
        for(int i=0;i<a.size();++i)
            for(int j=0;j<b.size();++j)
                n[i+j]+=a[i]*b[j];
        return n.check();
    }
    Wint& operator*=(Wint &a,const Wint &b) {return a=a*b;}
    Wint operator/(Wint a,const int &b)
    {
        Wint n; bool wp=0;
        for(int i=a.size()-1,t=0;i>=0;--i)
        {
            t=t*10+a[i];
            if(wp||t/b) wp=1,n.push_back(t/b);
            t%=b;
        }
        reverse(n.begin(),n.end());
        return n;
    }
    Wint& operator/=(Wint &a,const int &b) {return a=a/b;}
    void readX(Wint &n)
    {
        char s[1000]; scanf("%s",s); n.clear();
        for(int i=strlen(s)-1;i>=0;--i) n.push_back(s[i]-'0');
    }
    void writeX(Wint n)
    {
        if(n.empty()) putchar('0');
        for(int i=n.size()-1;i>=0;--i) putchar(n[i]+'0');
    }
    

    UPD2:又经过了许久,我的高精度最终版终于诞生(怎么这么中二)。
    新版在之前的Wint基础上再改良,变成了压 9 位的高精,用vector也不怕被卡了!
    为了与压位相匹配,实现了新的赋值函数,支持大整数读入。
    我持续了半年的伟业终于完成(

    typedef long long ll;
    struct Wint:vector<ll>
    {
        const static ll BIT=1e9;
        Wint(ll n=0) {push_back(n);check();}
        Wint& operator=(const char* num)
        {
            int Len=strlen(num)-1; clear();
            for(int i=Len;i>=0;i-=9)
            {
                push_back(0); ll w=1;
                for(int j=i;j>i-9&&j>=0;--j)
                    back()+=(num[j]^48)*w,w*=10;
            }
            return *this;
        }
        Wint& check()
        {
            while(!empty()&&!back()) pop_back();
            if(empty()) return *this;
            for(int i=1;i<size();++i)
                (*this)[i]+=(*this)[i-1]/BIT,
                (*this)[i-1]%=BIT;
            while(back()>=BIT)
            {
                push_back(back()/BIT);
                (*this)[size()-2]%=BIT;
            }
            return *this;
        }
    };
    bool operator<(Wint a,Wint b)
    {
        if(a.size()!=b.size()) return a.size()<b.size();
        for(int i=a.size()-1;i>=0;--i)
            if(a[i]!=b[i]) return a[i]<b[i];
        return 0;
    }
    bool operator>(Wint a,Wint b) {return b<a;}
    bool operator<=(Wint a,Wint b) {return !(a>b);}
    bool operator>=(Wint a,Wint b) {return !(a<b);}
    bool operator!=(Wint a,Wint b) {return a<b||b<a;}
    bool operator==(Wint a,Wint b) {return !(a<b)&&!(b<a);}
    Wint& operator+=(Wint &a,Wint b)
    {
        if(a.size()<b.size()) a.resize(b.size());
        for(int i=0;i<b.size();++i) a[i]+=b[i];
        return a.check();
    }
    Wint operator+(Wint a,Wint b) {return a+=b;}
    Wint& operator-=(Wint &a,Wint b)
    {
        for(int i=0;i<b.size();a[i]-=b[i],++i)
            if(a[i]<b[i])
            {
                int j=i+1;
                while(!a[j]) ++j;
                while(j>i) --a[j],a[--j]+=Wint::BIT;
            }
        return a.check();
    }
    Wint operator-(Wint a,Wint b) {return a-=b;}
    Wint operator*(Wint a,Wint b)
    {
        if(a.empty()&&b.empty()) return a;
        Wint n; n.assign(a.size()+b.size()-1,0);
        for(int i=0;i<a.size();++i)
            for(int j=0;j<b.size();++j)
                n[i+j]+=a[i]*b[j];
        return n.check();
    }
    Wint& operator*=(Wint &a,Wint b) {return a=a*b;}
    Wint operator/(Wint a,int b)
    {
        Wint n; bool wp=0; ll t=0;
        for(int i=a.size()-1;i>=0;--i)
        {
            t=t*Wint::BIT+a[i];
            if(wp||t/b) wp=1,n.push_back(t/b);
            t%=b;
        }
        reverse(n.begin(),n.end());
        return n;
    }
    Wint& operator/=(Wint &a,int b) {return a=a/b;}
    void readX(Wint &n) {char s[1000]; scanf("%s",s); n=s;}
    void writeX(Wint n)
    {
        if(n.empty()) {putchar('0'); return;}
        int Len=n.size()-1; printf("%lld",n[Len]);
        for(int i=Len-1;i>=0;--i) printf("%09lld",n[i]);
    }
    
  • 相关阅读:
    Java连接Oracle数据库
    团队冲刺阶段(八)
    团队冲刺阶段(七)
    团队冲刺进度(六)
    团队冲刺进度(五)
    团队冲刺进度(四)
    团队冲刺进度(三)
    团队冲刺进度(二)
    团队冲刺进度(一)
    软件需求规格所明书
  • 原文地址:https://www.cnblogs.com/wzzyr24/p/11423505.html
Copyright © 2011-2022 走看看