高精运算重载运算符模板

就是一个模板,不多说别的了。

#include<bits/stdc++.h>
using namespace std;
#define ST static
#define C const
#define int int
#define RT return
#define OP operator
#define LL long long
#define B bool
#define F friend
#define TH this
#define V void
#define W while
struct inf
{
    ST C int mod=100000000;
    ST C int width=8;
    B sign;
    size_t length;
    vector<int>num;
    inf(LL x=0){*TH=x;}
    inf(C string&x){*TH=x;}
    inf(C inf&x){*TH=x;}
    V cutLeadingZero(){W(num.back()==0&&num.size()!=1)num.pop_back();}
    V setLength()
    {
        cutLeadingZero();
        int tmp=num.back();
        if(tmp==0)length=1;
        else{length=(num.size()-1)*width;W(tmp>0)++length,tmp/=10;}
    }
    inf&OP=(LL x)
    {
        num.clear();
        if(x>=0)sign=1;else{sign=0;x=-x;}
        do{num.push_back(x%mod);x/=mod;}W(x>0);
        setLength();
        RT*TH;
    }
    inf&OP=(C string&str)
    {
        num.clear();
        sign=(str[0]!='-');
        int x,len=(str.size()-1-(!sign))/width+1;
        for(int i=0;i<len;i++)
        {
            int End=str.length()-i*width;
            int start=max((int)(!sign),End-width);
            sscanf(str.substr(start,End-start).c_str(),"%d",&x);
            num.push_back(x);
        }
        setLength();
        RT*TH;
    }
    inf&OP=(C inf&tmp)
    {
        num=tmp.num;
        sign=tmp.sign;
        length=tmp.length;
        RT*TH;
    }
    size_t size()C{RT length;}
    inf e(size_t n)C
    {
        int tmp=n%width;
        inf ans;
        ans.length=n+1;
        n/=width;
        W(ans.num.size()<=n)
            ans.num.push_back(0);
        ans.num[n]=1;
        W(tmp--)ans.num[n]*=10;
        RT ans* (*TH);
    }
    inf abs()C
    {
        inf ans(*TH);
        ans.sign=1;
        RT ans;
    }
    C inf&OP+()C{RT*TH;}
    inf OP+(C inf&b)C
    {
        if(!b.sign)RT*TH-(-b);
        if(!sign)RT b-(-*TH);
        inf ans;
        ans.num.clear();
        for(int i=0,g=0;;i++)
        {
            if(g==0&&i>=num.size()&&i>=b.num.size())break;
            int x=g;
            if(i<num.size())x+=num[i];
            if(i<b.num.size())x+=b.num[i];
            ans.num.push_back(x%mod);
            g=x/mod;
        }
        ans.setLength();
        RT ans;
    }
    inf OP-()C
    {
        inf ans(*TH);
        if(ans!=0)ans.sign=!ans.sign;
        RT ans;
    }
    inf OP-(C inf&b)C
    {
        if(!b.sign)RT*TH+(-b);
        if(!sign)RT-((-*TH)+b);
        if(*TH<b)RT-(b-*TH);
        inf ans;
        ans.num.clear();
        for(int i=0,g=0;;i++)
        {
            if(g==0&&i>=num.size()&&i>=b.num.size())break;
            int x=g;
            g=0;
            if(i<num.size())x+=num[i];
            if(i<b.num.size())x-=b.num[i];
            if(x<0)
            {
                x+=mod;
                g=-1;
            }
            ans.num.push_back(x);
        }
        ans.setLength();
        RT ans;
    }
    inf OP*(C inf&b)C
    {
        int lena=num.size(),lenb=b.num.size();
        vector<LL> ansLL;
        for(int i=0;i<lena+lenb;i++)ansLL.push_back(0);
        for(int i=0;i<lena;i++)
            for(int j=0;j<lenb;j++)
                ansLL[i+j]+=(LL)num[i]* (LL)b.num[j];
        W(ansLL.back()==0&&ansLL.size()!=1)ansLL.pop_back();
        int len=ansLL.size();
        LL g=0,tmp;
        inf ans;
        ans.sign=(ansLL.size()==1&&ansLL[0]==0)||(sign==b.sign);
        ans.num.clear();
        for(int i=0;i<len;i++)
        {
            tmp=ansLL[i];
            ans.num.push_back((tmp+g)%mod);
            g=(tmp+g)/mod;
        }
        if(g> 0)ans.num.push_back(g);
        ans.setLength();
        RT ans;
    }
    inf OP/(C LL&b)C
    {
        inf c;
        c.num.clear();
        for(int i=0;i<num.size();i++)
            c.num.push_back(0);
        LL g=0;
        for(int i=num.size()-1;i>=0;i--)
        {
            c.num[i]=int((num[i]+g* mod)/b);
            g=num[i]+g* mod-c.num[i]* b;
        }
        for(int i=num.size()-1;c.num[i]==0;i--)
            c.num.pop_back();
        RT c;
    }
    inf OP/(C inf&b)C
    {
        inf aa((*TH).abs());
        inf bb(b.abs());
        if(aa<bb)RT 0;
        char*str=new char[aa.size()+1];
        memset(str,0,sizeof(char)*(aa.size()+1));
        inf tmp;
        int lena=aa.length,lenb=bb.length;
        for(int i=0;i<=lena-lenb;i++)
        {
            tmp=bb.e(lena-lenb-i);
            W(aa>=tmp)
            {
                ++str[i];
                aa=aa-tmp;
            }
            str[i]+='0';
        }
        inf ans(str);
        delete[]str;
        ans.sign=(ans==0||sign==b.sign);
        RT ans;
    }
    inf OP%(C LL&b)C
    {
        LL ans=0;
        for(int i=num.size()-1;i>=0;i--)ans=(ans*mod+num[i])%b;
        RT ans;
    }
    inf OP%(C inf&b)C{RT*TH-*TH/b*b;}
    inf&OP++(){*TH=*TH+1;RT*TH;}
    inf&OP--(){*TH=*TH-1;RT*TH;}
    inf&OP+=(C inf&b){*TH=*TH+b;RT*TH;}
    inf&OP-=(C inf&b){*TH=*TH-b;RT*TH;}
    inf&OP*=(C inf&b){*TH=*TH*b;RT*TH;}
    inf&OP/=(C LL&b){*TH=*TH/b;RT*TH;}
    inf&OP/=(C inf&b){*TH=*TH/b;RT*TH;}
    inf&OP%=(C LL&b){*TH=*TH%b;RT*TH;}
    inf&OP%=(C inf&b){*TH=*TH%b;RT*TH;}
    B OP<(C inf&b)C
    {
        if(sign&&!b.sign)RT 0;
        if(!sign&&b.sign)RT 1;
        if(!sign&&!b.sign)RT-b<-*TH;
        if(num.size()!=b.num.size())RT num.size()<b.num.size();
        for(int i=num.size()-1;i>=0;i--)
            if(num[i]!=b.num[i])RT num[i]<b.num[i];
        RT 0;
    }
    B OP>(C inf&b)C{RT b<*TH;}
    B OP<=(C inf&b)C{RT!(b<*TH);}
    B OP>=(C inf&b)C{RT!(*TH<b);}
    B OP!=(C inf&b)C{RT b<*TH||*TH<b;}
    B OP==(C inf&b)C{RT!(b<*TH)&&!(*TH<b);}
    B OP||(C inf&b)C{RT*TH!=0||b!=0;}
    B OP&&(C inf&b)C{RT*TH!=0&&b!=0;}
    B OP!(){RT(B)(*TH==0);}
    F ostream&OP<<(ostream&out,C inf&x)
    {
        if(!x.sign)out<<'-';
        out<<x.num.back();
        for(int i=x.num.size()-2;i>=0;i--)
        {
            char buf[10];
            sprintf(buf,"%08d",x.num[i]);
            for(int j=0;j<strlen(buf);j++)out<<buf[j];
        }
        RT out;
    }
    F istream&OP>>(istream&in,inf&x)
    {
        string str;
        in>>str;
        size_t len=str.size();
        int start=0;
        if(str[0]=='-')start=1;
        if(str[start]=='\0')
            RT in;
        for(int i=start;i<len;i++)
            if(str[i]<'0'||str[i]>'9')
                RT in;
        x.sign=!start;
        x=str.c_str();
        RT in;
    }
    inf pow(int n)
    {
        inf ans=1,base=*TH;
        W(n)
        {
            if(n&1)ans=ans*base;
            base=base*base;
            n>>=1;
        }
        RT ans;
    }
};
int main()
{
    int n;
    inf ans;
    ans=1;
    cin>>n;
    for(int i=1;i<=n;i++)
        ans*=i;
    cout<<ans<<endl;
    RT 0;
}

 

posted @ 2019-08-08 09:58  神之右大臣  阅读(373)  评论(0编辑  收藏  举报