高精度模板(Big_Int)

你还在为刷题时看到的高精度预警而苦恼吗?

你还在因为高精度难写而放弃宝贵的分数吗?

不用担心!让高精度模板 来帮助你!

目前已知bug:

长度最大值只能开到54724,超过这个值会爆炸(无法调试),目前原因未知

2018.09.07更新:

1、优化了高精乘以低精的速度。
2、输出优化,可使用.output()函数输出。(基于输出挂)@Jesse666
ps:那个长度最大值的bug有可能是栈空间的问题,可以试试更改栈空间有没有效果


2018.09.01更新:

1、鉴于@Jesse666同学的建议,本次更新增加了基于牛顿迭代法的高精度开平方运算。
2、我还没有掌握好关于迭代次数的问题,所以在超大整数(过100位)可能会出现精度不正确的bug,请见谅。
3、目前迭代次数为长度length*10,有更好的迭代次数计算方法可以在我的blog下留言。

ps:下面那个更新实际上是8.31晚上11点更新的,然而更新完已经9.1了,所以标号为9.1。

pps:潜在bug:该高精度模板长度最大值只能设置为54724(或者更少),目前还没有找到明确原因,有人知道的可以私信我。


2018.09.01更新:

1、更改了代码顺序,并调整了格式,阅读代码以及调试代码更加方便。
2、四则运算现在可以参与int类型(即可以Big_Int+int。
3、完善了四则运算的+=、-=等操作。


2018.08.31更新:
在集训的最后一天,我学会了高精度除法,所以顺便做出来了除法的模板。本次更新内容:

1、增加++、--等递增递减运算,平均速度比+1要快。
2、增加高精度除法/运算。
3、增加高精度取模%运算。
4、增加了高精幂(请使用a.pow(b))运算。
5、增加了基于十进制的左移<<、右移>>运算(是基于十进制,所以等于*10和/10。比乘除法快)。
6、增加了使用int与char数组初始化的功能
7、修复了清空big_int的潜在正负性bug

如果以后发现bug,还会再更新的。喜欢请点个赞哦~

链接:https://pan.baidu.com/s/1axc75pHjtxD33U6V_6HBOg 密码: p0w7

转载请注明出处及作者。

#pragma GCC optinize(3)
#pragma comment(linker, "/STACK:102400000,10240000")
#include <bits/stdc++.h>
#define LEN 35663//100001
using namespace std;
class Big_Int{
    //54724
    private:
        int a[LEN];
        int len;
        bool f,p;
    public:
        //初始化构造函数运算
        void clear()
        {
            memset(a,0,sizeof a);
            len=1;
           f=0;
            p=0;
        }
        Big_Int()
        {
            clear();
        }
        Big_Int(int x)
        {
            clear();
            (*this)=x;
        }
        Big_Int(const Big_Int &x)
        {
            clear();
            (*this)=x;
        }

    //赋值运算 

        Big_Int operator =(const char *ch)
        {
            len=strlen(ch);
            if(ch[0]=='-')
            {
                f=1;len--;
                for(int i=1;i<=len;i++) a[i]=ch[len-i+1]-'0';
                return *this;
            }
            for(int i=1;i<=len;i++) a[i]=ch[len-i]-'0';
            return *this;
        }
        Big_Int operator =(const int d)
        {
            char ch[LEN];
            sprintf(ch,"%d",d);
            *this=ch;
            return *this;
        }

    //四则基本运算 

        Big_Int operator +(Big_Int b)
        {
            if(f==1&&b.f==0)
            {
                f=0;
                return b-(*this);
            }
            else if(f==0&&b.f==1)
            {
                b.f=0;
                return (*this)-b;
            }
            Big_Int c;
            c.clear();
            int l=max(len,b.len);
            for(int i=1;i<=l;i++)
            {
                c.a[i]+=a[i]+b.a[i];
                c.a[i+1]=c.a[i]/10;
                c.a[i]%=10;
            }
            if(c.a[l+1]) l++;
            c.len=l;
            c.f=f&&b.f;
            return c;
        }
        Big_Int operator -(Big_Int b)
        {

            if(f==1&&b.f==0)
            {
                b.f=1;
                return b+(*this);
            }
            if(f==0&&b.f==1)
            {
                b.f=0;
                return b+(*this);
            }
            if(f==1&&b.f==1)
            {
                b.f=0;
                return b+(*this);
            }
            Big_Int c;
            c.clear();
            if((*this)<b)
            {
                swap(*this,b);
                c.f=1;
            }
            int l=max(len,b.len);
            for(int i=1;i<=l;i++)
            {
                c.a[i]+=a[i]-b.a[i];
                if(c.a[i]<0) c.a[i+1]--,c.a[i]+=10;
            }
            while(c.a[l]==0&&l>0) l--;
            if(l==0) l=1;
            c.len=l;
            return c;
        }
        Big_Int operator *(Big_Int b)
        {
            Big_Int c;
            c.clear();
            int l=len+b.len-1;
            for(int i=1;i<=len;i++)
            {
                for(int j=1;j<=b.len;j++)
                {
                    c.a[i+j-1]+=a[i]*b.a[j];
                    c.a[i+j]+=c.a[i+j-1]/10;
                    c.a[i+j-1]%=10;
                }
            }
            while(c.a[l+1]!=0) l++;
            c.len=l;
            if((f==0&&b.f==1)||(f==1&&b.f==0)) c.f=1;
            return c;
        }
        Big_Int operator /(Big_Int b)
        {
            if(b==0)
            {
                throw 0x7f;
            }
            Big_Int a=(*this),c,t;
            c.len=len-b.len+1;
            for(int i=c.len;i>=0;i--)
            {
                if(a==0) break;
                t.clear();
                t=b<<i;
                while(t<=a)
                {c.a[i+1]++;a-=t;}
            }
            while(!c.a[c.len]&&c.len>0) c.len--;
            if(c.len==0) c.len=1;
            if(f==0&&b.f==1) c.f=1;
            else if(f==1&&b.f==0) c.f=1;
            return c;
        }
        Big_Int operator %(Big_Int b)
        {
            Big_Int c=(*this)/b;
            b=b*c;
            return (*this)-b;
        }       

        //比较运算 

        bool operator <=(Big_Int b)
        {
            return ((*this)<b||(*this)==b);
        }
        bool operator >=(Big_Int b)
        {
            return ((*this)>b||(*this)==b);
        }
        bool operator <(Big_Int b)
        {
            if((*this)==b) return 0;
            if(f&&!b.f) return 1;
            else if(!f&&b.f) return 0;
            else if(f==b.f&&f==0&&len<b.len) return 1;
            else if(f==b.f&&f==0&&len>b.len) return 0;
            else if(f==b.f&&f==1&&len<b.len) return 0;
            else if(f==b.f&&f==1&&len>b.len) return 1;
            else
            {
                int flag=-1;
                for(int i=len;i>=1;i--)
                {
                    if(a[i]>b.a[i])
                    {
                        flag=0;
                        break;
                    }
                    else if(a[i]<b.a[i])
                    {
                        break;
                    }
                }
                if(f==1) flag=!flag;
                else if(f==-1) return 0;
                return flag;
            }
        }
        bool operator ==(Big_Int b)
        {
            if(f!=b.f) return 0;
            if(len!=b.len) return 0;
            for(int i=len;i>=1;i--)
            {
                if(a[i]!=b.a[i]) return 0;
            }
            return 1;
        }
        bool operator !=(Big_Int b)
        {
            return !((*this)==b);
        }
        bool operator !=(int b)
        {
            return !((*this)==b);
        }
        bool operator ==(int b)
        {
            Big_Int a=b;
            return a==(*this);
        }
        bool operator >(Big_Int b)
        {
            if(!((*this)<b)&&!((*this)==b)) return 1;
            else return 0;
        }

        //递增(减)运算 

        Big_Int operator ++(int)
        {
            if(f==1&&!p)
            {
                p=1;
                (*this)--;
                return *this;
            }
            a[1]++;
            int t=1;
            while(a[t]>9)
            {
                a[t+1]++;
                a[t]%=10;
                t++;
            }
            while(a[len+1]) len++;
            if(len==1&&a[len]==0) f=0;
            p=0;
            return *this;
        }
        Big_Int operator --(int)
        {
            if(f==1&&!p)
            {
                (*this)++;
                p=1;
                return *this;
            }
            int t=1;
            a[t]--;
            while(a[t]<0)
            {
                a[t+1]--;
                a[t]+=10;
                t++;
            }
            while(a[len+1]) len++;
            if(len==1&&a[len]==0) f=0;
            p=0;
            return *this;
        }

        //四则运算扩展 

            //加法相关 

        Big_Int operator +(int b)
        {
            Big_Int c=b;
            return (*this)+c;
        }
        void operator +=(Big_Int b)
        {
            (*this)=(*this)+b;
        }
        void operator +=(int b)
        {
            Big_Int c=b;
            (*this)=(*this)+c;
        }
            //减法相关 

        Big_Int operator -(int b)
        {
            Big_Int c=b;
            return (*this)-c;
        }
        void operator -=(Big_Int b)
        {
            (*this)=(*this)-b;
        }
        void operator -=(int b)
        {
            Big_Int c=b;
            (*this)=(*this)-b;
        }       

            //乘法相关
        inline Big_Int operator *(int b)
        {
            /*Big_Int c=b;
            return (*this)*c;*/
            Big_Int c;
            for(int i=1;i<=len;i++)
            {
                c.a[i]+=a[i]*b;
                c.a[i+1]=c.a[i]/10;
                c.a[i]%=10;
            }
            c.len=len;
            while(c.a[c.len+1]!=0)
            {
                c.len++;
                c.a[c.len+1]=c.a[c.len]/10;
                c.a[c.len]%=10;
            }
            return c;
        }
        void operator *=(Big_Int b)
        {
            (*this)=(*this)*b;
        }
        void operator *=(int b)
        {
            (*this)=(*this)*b;
        }

            //除法相关 

        Big_Int operator /(int b)
        {
            Big_Int c=b;
            return (*this)/c;
        }
        void operator /=(int b)
        {
            Big_Int c=b;
            (*this)=(*this)/c;
        }
        void operator /=(Big_Int b)
        {
            (*this)=(*this)/b;
        }

            //取模相关 

        Big_Int operator %(int b)
        {
            Big_Int c=b;
            return (*this)%c;
        }
        void operator %=(int b)
        {
            Big_Int c=b;
            (*this)=(*this)%c;
        }
        void operator %=(Big_Int b)
        {
            (*this)=(*this)%b;
        }          

        //特殊运算
        Big_Int abs()
        {
            Big_Int c=(*this);
            c.f=0;return c;
        }
        Big_Int operator <<(int b)  //基于十进制的左移,所以是等同于*10
        {
            Big_Int c;
            for(int i=b+1;i<=len+b;i++)
              c.a[i]=a[i-b];
            c.len=len+b;
            return c;
        }
        Big_Int operator >>(int b)
        {
            Big_Int c;
            for(int i=b+1;i<=len;i++)
            {
                c.a[i-b]=a[i];
            }
            c.len=len-b;
            return c;
        }
        Big_Int pow(Big_Int b)
        {
            Big_Int a=(*this),ans=1;
            while(b!=0)
            {
                if(b.a[1]&1) ans*=a;
                a*=a;
                b/=2;
            }
            return ans;
        }
        Big_Int pow(int b)
        {
            Big_Int a=(*this),ans=1;
            while(b!=0)
            {
                if(b&1) ans*=a;
                a*=a;
                b/=2;
            }
            return ans;
        }
        Big_Int sqrt()
        {
            Big_Int x=(*this),a=(*this);
            for(int i=1;i<=len*10;i++) x=(x+a/x)/2;
            return x;
        }
        //转换函数
        void output()
        {
            while(a[len]==0) --len;
            for(register int i=len;i>=1;--i) putchar(a[i]+'0');
        }
        string cpp_str()
        {
            string str;
            if(len==0)
            {
                str="0";
                return str;
            }
            if(f==1&&!(len==1&&a[1]==0)) str.push_back('-');
            for(int i=len;i>=1;i--) str.push_back(a[i]+'0');
           return str;
        }
}a;
istream& operator >>(istream &in,Big_Int &a)
{
    string str;
    in>>str;
    a=str.c_str();
    return in;
}
ostream& operator <<(ostream &out,Big_Int &a)
{
    out<<a.cpp_str();
    return out;
}
int main()
{
}

原文地址:https://www.cnblogs.com/MaxDYF/p/9792688.html

时间: 2024-11-10 13:46:16

高精度模板(Big_Int)的相关文章

[Template]高精度模板

重新写一下高精度模板(不要问我为什么) 自认为代码风格比较漂亮(雾 如果有更好的写法欢迎赐教 封装结构体big B是压位用的进制,W是每位长度 size表示长度,d[]就是保存的数字,倒着保存,从1开始 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const i

高精度模板(不定时更新)

以前写高精度基本都是抄别人的--这次要改变一下了-- 现在的高精度模板还是很简陋的,只支持高精加,减,乘,高精除低精,高精模低精,高精快速幂,高精比较大小,没了. 或许以后会不定期更新一下--毕竟这个还是比较ca的. 直接一股脑全贴上来吧--注意所有的元素都是倒叙存储的,想要改成压位的很简单,只要改一下模数,改一下输入输出即可. 也可以支持不同进制的运算,都是很好改的. struct big { int f[M],len; big() { memset(f,0,sizeof(f)),len =

[note]高精度模板

高精度模板 先定义一个struct struct gj{ int l,s[N]; bool fh; void Print(){ if(fh)putchar('-'); for(int i=l;i>=1;i--)printf("%d",s[i]); puts(""); } }blank; 高精+高精 加之前判断一下符号 一负一正转成减法 gj operator +(gj x,gj y){ gj z=blank;z.l=max(x.l,y.l); for(int

高精度模板(修改中)

这个是一个高精度的模板,还在完成中... 1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<cstring> 7 #include<vector> 8 #define xh(a,b,c)for(int a=(b);a<=(c);a++) 9 #de

真&#183;纯手撸高精度模板

耗时(50分钟)不压位 内容只有高精度+-*,因为其他我不会写QAQ~ 均ACluogu,codevs #include<bits/stdc++.h> using namespace std; const int N =(int)1e5+10; struct bignum { int m[N],len; char str[N]; int ok; bignum() {ok=1;len=1,memset(m,0, sizeof(m));} void in() {scanf("%s&quo

高精度模板2(带符号压位加减乘除开方封包)

原来的那个模板:http://www.cnblogs.com/iwtwiioi/p/3991331.html 估计已经不用了. 现在我重新封包好了一个,一定很好用QAQ 加减乘除带开方带压位带重载运算符 注意一下符号即可,一定写的时候要手推四种情况!! 然后在重载<的时候,一定要注意同时判断!!!!要不然又错.. struct big { typedef ll INT; static const INT S=100000000; static const int S_n=9; static co

大整数类BIGN的设计与实现 C++高精度模板

首先感谢刘汝佳所著的<算法竞赛入门经典>. 众所周知,C++中储存能力最大的unsigned long long 也是有着一个上限,如果我们想计算非常大的整数时,就不知所措了,所以,我写了一个高精度类,允许大整数的四则运算 这个类利用字符串进行输入输出,并利用数组进行储存与处理,通过模拟四则运算,可以计算很大的整数的加减乘除比大小. 贴上我的代码: #include<string> #include<iostream> #include<iosfwd> #i

高精度模板总结

高精度取余 1.高精度取单精度 int hmod(string a,int b)//高精度取余单精度 输出余数 { int temp=0; unsigned long len=a.length(); for(int i=0;i<len;i++) temp=(temp*10+a[i]-'0')%b; return temp; }

【高精度】【模板】高精度模板

没有什么好说的,照着模板写就是了,稍微用了点手段,支持负数的减法了 1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<algorithm> 5 #include<vector> 6 #include<iostream> 7 using namespace std; 8 const int maxn=510; 9 struct bigint 10 {