高精度入土

既然是高精度入土,分享一个姬昌无比的恶臭高精,可以处理负数。

\(M\) 用来调节字符串的长度,重载了 \(+\) \(-\) \(\times\) \(\div\) \(\%\) 五则运算。甚至还有快速幂。

重载了 \(\leq\) 等等二元关系

一些函数

GJ tmp;
turnGJ(1);  //将整型的 1 转换成 GJ 类型的
tmp.clean();   //将这个东西的每一位变成零(初始化)
tmp.Read();    //快读它
tmp.Write(0 or 1) // 1 表示带换行的输出,而 0 表示不换行
tmp.itoBig(1) //将 tmp 初值赋为 1
tmp.qpow(tmp,1000) //求 tmp^1000
struct GJ{
    static const int M=20087;
    int num[M+10],len;
    bool __fu;
    GJ(){clean();}
    void clean(){
        memset(num,0,sizeof(num));
        len=1;
        __fu=0;
    }
    void Read(){
        char str[M+10];
        scanf("%s",str);
        len=strlen(str);
        if(str[0]=='-'){
            __fu=1;
            for(register int i=1;i<len;++i)
               num[i]=str[len-i]-'0';
            len--;
        }else{
            for(register int i=1;i<=len;++i)
                num[i]=str[len-i]-'0';
        }
    }
    void Write(bool IakIOI){
        if(__fu) putchar('-');
        for(register int i=len;i>=1;--i)
            putchar(num[i]+'0');
        if(IakIOI) puts("");
        else /*您输出了空气。*/;
    }
    template <typename T>inline void itoBig(T x){
        clean();
        while(x!=0){
            num[len++]=x%10;
            x/=10;
        }
        if(len!=1)len--;
    }
    template <typename T>inline GJ turnGJ(T x){
        GJ ___gj;
        if(x<0){
            x=abs(x);
            ___gj.__fu=1;
        }
        while(x!=0){
            ___gj.num[___gj.len++]=x%10;
            x/=10;
        }
        if(___gj.len!=1)___gj.len--;
        return ___gj;
    }
    bool operator < (const GJ &cmp)const{
        if(len!=cmp.len) return len<cmp.len;
        for(int i=len;i>=1;--i)
            if(num[i]!=cmp.num[i]) return num[i]<cmp.num[i];
        return false;
    }
    bool operator > (const GJ &cmp)const{return cmp<*this;}
    bool operator <= (const GJ &cmp)const{return !(cmp<*this);}
    bool operator != (const GJ &cmp)const{return cmp<*this||*this<cmp;}
    bool operator == (const GJ &cmp)const{return !(cmp<*this||*this<cmp);}
    GJ operator + (const GJ &A)const{
        if(A.__fu&&__fu){
            auto _____tmp=*this,____tmp=A;
            _____tmp.__fu=0;____tmp.__fu=0;
            auto ___S=_____tmp+____tmp;
            ___S.__fu=1;
            return ___S;
        }
        if(A.__fu){
            auto ____tmp=A;
            ____tmp.__fu=0;
            auto ___S=*this-____tmp;
            return ___S;
        }
        if(__fu){
            auto ___tmp=*this;
            ___tmp.__fu=0;
            auto ___S=A-___tmp;
            return ___S;
        }
        GJ S;
        S.len=max(len, A.len);
        for(int i=1;i<=S.len;++i){
            S.num[i]+=num[i]+A.num[i];
            if(S.num[i]>=10){
                S.num[i]-=10;
                S.num[i+1]++;
            }
        }
        while(S.num[S.len+1])S.len++;
        return S;
    }
    GJ operator - (const GJ &A)const{
        if(A.__fu&&__fu){
            auto _S=A;
            _S.__fu=0;
            auto __S=*this+_S;
            return __S;
        }
        if(A.__fu){
            auto _S=A;
            _S.__fu=0;
            auto __S=*this+_S;
            return __S;
        }
        if(__fu){
            GJ _tmpp,_tmppp;
            _tmpp=*this;
            _tmpp.__fu=0;
            _tmppp=A;
            _tmppp.__fu=0;
            auto SSS=_tmpp+_tmppp;
            SSS.__fu=1;
            return SSS;
        }
        if(*this<A){
            putchar('-');
            auto S=A-*this;
            return S;
        }
        GJ S;
        S.len=max(len,A.len);
        for(int i=1;i<=S.len;++i){
            S.num[i]+=num[i]-A.num[i];
            if(S.num[i]<0){
                S.num[i]+=10;
                S.num[i+1]--;
            }
        }
        while(!S.num[S.len]&&S.len>1)S.len--;
        return S;
    }
    GJ operator * (const GJ &A)const{
        GJ S;
        if((A.__fu xor __fu)) S.__fu=1;
        if((A.len==1&&A.num[1]==0)||(len==1&&num[1]==0)) return S;
        S.len=A.len+len-1;
        for(int i=1;i<=len;++i)
            for(int j=1;j<=A.len;++j){
                S.num[i+j-1]+=num[i]*A.num[j];
                S.num[i+j]+=S.num[i+j-1]/10;
                S.num[i+j-1]%=10;
            }
        while(S.num[S.len+1])S.len++;
        return S;
    }
    GJ operator / (const GJ &A)const{
        GJ S;
        if((A.__fu xor __fu)) S.__fu=1;
        if((A.len==1&&A.num[1]==0)||(len==1&&num[1]==0))return S;
        GJ R,N;
        S.len=0;
        for(int i=len;i>=1;--i){
            N.itoBig(10);
            R=R*N;
            N.itoBig(num[i]);
            R=R+N;
            int flag=-1;
            for(register int j=1;j<=10;++j){
                N.itoBig(j);
                if(N*A>R){
                    flag=j-1;
                    break;
                }
            }
            S.num[++S.len]=flag;
            N.itoBig(flag);
            R=R-N*A;
        }
        for(register int i=1;i<=len/2;++i)swap(S.num[i],S.num[len-i+1]);
        while(!S.num[S.len]&&S.len>1)S.len--;
        return S;
    }
    GJ operator % (const GJ &A)const{
        GJ S;
        GJ P=*this/A;
        S=*this-P*A;
        return S;
    }
    GJ qpow (const GJ &A,int buff) const{
	if(buff==1) return A;
        GJ f=qpow(A,buff/2);
        if(buff&1) return f*f*A;
        else return f*f;
    }
    void operator = (const GJ &A){
        for(register int i=1;i<=A.len;++i)
            num[i]=A.num[i];
        len=A.len;
        __fu=A.__fu;
    }
};
posted @ 2021-12-14 20:40  Mercury_City  阅读(32)  评论(0编辑  收藏  举报