跳转至

高精度

专题 | 高精度&快读快输

小技巧

如果只是略微超过long long范围,可以使用__int128

详解__int128 - FReQuenter - 博客园

__int128目前已知可以使用

  • <比较大小

  • 四则运算

  • 取模

高精度

介绍:

我们有些时候要对很大的数(超出long long范围)进行加减乘除,普通的运算符无法完成,我们就需要使用高精度

代码

#include 
using namespace std;

//请将函数复制在你的程序里,不用直接从本文件调用!)

//前置(定义变量)(将此代码复制在主函数外)
string sa, sb;
int la, lb, lc;
int a[99999], b[99999], c[99999];
//前置(输入并处理)(放在运算函数的前面)
cin >> sa >> sb;
la = sa.size();
lb = sb.size();
lc = max(la, lb);
for (int i = 0; i < la; i++)
    a[la - i] = sa[i] - '0';
for (int i = 0; i < lb; i++)
    b[lb - i] = sb[i] - '0';
//输出结果的代码
for (int i = lc; i > 0; i--)
    cout << c[i];

大数比较(注意不要直接比较两个高精度!也不要使用max,min函数!)

string Max(string a,string b){
    if(a.size()==b.size())return a>b?a:b;
    return a.size()>b.size()?a:b;
}

大数加法

//参数(加数,加数,进制(<=10))

void add(int B) {

    for (int i = 0; i <= lc; i++) //先加
        c[i] = a[i] + b[i];

    for (int i = 0; i <= lc; i++) { //进位
        c[i + 1] += c[i] / B;
        c[i] %= B;
    }

    if (c[lc + 1] != 0)
        lc++;
    while (c[lc] == 0 && lc > 1)
        lc--;//去前导0

}

大数减法

void sub() {

    for (int i = 0; i <= lc; i++)
        c[i] = a[i] - b[i];

    for (int i = 0; i <= lc; i++) {
        if (c[i] < 0) {
            c[i] += 10;
            c[i + 1]--;
        }
    }

    while (c[lc] == 0 && lc > 1)
        lc--;
}

大数乘法

高精度乘低精度

void mul_small(int x) {

    for (int i = 0; i <= lc; i++) //先加
        c[i] = a[i] * x;

    for (int i = 0; i <= lc; i++) { //进位
        c[i + 1] += c[i] / 10;
        c[i] %= 10;
    }

    if (c[lc + 1] != 0)
        lc++;
    while (c[lc] == 0 && lc > 1)
        lc--;//去前导0

}

高精度乘高精度

string s1, s2;

string mul() {
    int n1 = s1.size(), n2 = s2.size();
    string res(n1 + n2, '0');
    for (int i = n1 - 1; i >= 0; i--) {
        for (int j = n2 - 1; j >= 0; j--) {
            int t = res[i + j + 1] - '0' + (s1[i] - '0') * (s2[j] - '0'); //加本位
            res[i + j] += t / 10;
            res[i + j + 1] = t % 10 + '0';
        }
    }
    for (int i = 0; i < n1 + n2; i++)
        if (res[i] != '0')
            return res.substr(i);
    return "0";
}

int main() {
    cin >> s1 >> s2;
    cout << mul() << endl;
    return 0;
}

高精乘高精的压位高精度乘法(23.10.7)

/*////////ACACACACACACAC///////////
       . Code  by  Ntsc .
       . Earn knowledge .
/*////////ACACACACACACAC///////////

#include<bits/stdc++.h>
#define int long long
#define db double
#define rtn return
using namespace std;

const int N=1e5+5;
const int M=1e5;
const int Mod=1e5;
const int INF=1e5;

int n,m,p,q,T;
string sa,sb;

struct node{
    int res[N];//define为ll ,压8位 
    int len;
};
node mul(node a,node b){
    node c;
    int n=a.len,m=b.len;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            c.res[i+j-1]+=a.res[i]*b.res[j];
        }
    }

    for(int i=1;i<=n+m-1;i++){
        c.res[i+1]+=c.res[i]/100000000;
        c.res[i]%=100000000;
    }

    c.len=n+m-1; 
    while(c.res[c.len+1])c.len++;
    return c;
}

node init(string s){//字符串转压位数组
    node a;
    a.len=0;
    int l=s.size();
    int t=0;
    for(int i=l-1,k=0;i>=0;i--){
        k++;
        t+=(s[i]-'0')*pow(10,k-1);
        if(k==8||i==0){
            a.res[++a.len]=t;
            t=0;k=0;
        }
    }
    return a;
}

inline void out(node a){//请开栈! //输出压位数组
    cerr<<a.len<<endl;
    printf("%lld",a.res[a.len]);
    for(int i=a.len-1;i;i--)printf("%08lld",a.res[i]);
}

signed main(){
    cin>>sa>>sb;

    node a=init(sa);
    node b=init(sb);
    node c=mul(a,b);

    out(c);
    return 0;
}

补充知识:printf固定前缀0输出

int a = 4;
printf("%03d",a);

输出:004

也可以用 * 代替位数,在后面的参数列表中用变量控制输出位数;

int a = 4;
int n = 3;
printf("%0*d",n,a);

输出:004

大数除法(大数/单精度)

void div_small(int x) {
    lc = la;
    for (int i = 0; i < lc; i++) {
        c[i] = a[i] / x;
        a[i + 1] += (a[i] % x) * 10;
    }

    c[lc] = a[lc] / x;
    int yu = a[lc] % x;

}
string divv(string a,int b){
    // int b=atoi(strb.c_str());
    int res=0;
    string r="";
    for(int i=0;i<a.size();i++){
        res*=10;
        res+=a[i]-'0';
        if(res>=b){
            r=r+(char)(res/b+'0');
            res=res-res/b*b;    
        }
        else{
            if(r!="")r=r+'0';
        }

    }
    return r;
}

//大数除法(大数/大数)

void div_big() {}

小数除法(用于求出小数点后>15位)

int a,b,c,f[N],cnt[N],l,r,tend=INF;

void xiaosc(int a,int b) {//a÷b
    cout<<a/b;
    if(!(a%b))return ;//可以整除
    cout<<'.';
    int d=a%b; 
    for(int i=1;i;i++){
        d*=10;
        if(!d){//除尽了
            tend=i;break;
        }
        if(cnt[d]){//找到循环节
            l=cnt[d];r=i-1;break;
        }
        cnt[d]=i;
        int t=d/b;
        d-=t*b;
        f[i]=t; 
    }
  //输出循环节,会用括号括起来
    for(int i=1;i;i++){
        if(i==tend)break;
        if(i==l)cout<<'(';
        cout<<f[i];
        if(i==r){
            cout<<')';return ;
        }
    }
    return ;
}

速用模板

压位 打包

接口:

a.cin();//输入
a.cout(1);//输出且换行

代码

#undef int //不能int->LL
const int MAXL=1e4+5; //MAXL不能大,MAXL=数字长度最大值 注意计算空间占用!

typedef long long LL;
const int base = 1e8;
int aux[MAXL];//储存原始数据 
class HighPrecision{//高精度压位模板 
    private:
        int p[MAXL], sz;//类的私有成员 
    public://区域一:
        void cin() {//读入函数 
            this -> clear();//清空对象 
            memset(aux, 0, sizeof(aux));
            int tot = 0,x = 0, y, k = 1;
            char ch = getchar();

            int fu = 1; //符号判断
            for (; ch < '0' || ch > '9'; ch = getchar()) 
                if (ch == '-') fu *= -1;

            for (; ch >= '0' && ch <= '9'; ch = getchar()){
                if(tot==1&&aux[tot]==0)aux[tot] = ch - '0';
                else aux[++tot] = ch - '0';//处理前缀零和读入零的情况 
            }
            sz = (tot + 7) / 8;//计算位数 
            y = (tot - 1) % 8 + 1;//最高位标记 
            for (int i = tot; i >= y; i -= 8, x=0){
                for(int j=7;j>=0;--j){//压位(亿进制) 
                    if(i <= j)continue;//最高位处理 
                    x = x * 10 + aux[i - j];
                }
                p[k++] = x;//对每一位进行储存 
            }
            p[sz] *= fu;//标记符号 
        }
        void cout(bool u = false){//读出函数 
            if(sz == 0) { printf("inf"); return;}//异常状况 
            printf("%d", p[sz]);//先输出首位带符号 
            for(int i = sz - 1; i; --i)
                printf("%08d", p[i]);
            if(u) printf("\n");//换行 
        } 
    public://区域二: 
        HighPrecision operator = (const int &d){//重载= (int)
            int b = d;

            int fu = 1;//符号判断 
            if(b < 0) b *= -1, fu = -1;

            this -> clear();//清空对象 
            do {//用do~while处理d为零的状况 
                p[++sz] = b % base;
                b /= base;
            } while(b);
            p[sz] *= fu;
            return *this;
        }
        HighPrecision operator = (const LL &d){//重载= (long long) 
            LL b = d;

            int fu = 1;//符号判断           
            if (b < 0) b *= -1, fu = -1; 

            this -> clear();//清空对象 
            do {//用do~while处理d为零的状况 
                p[++sz] = b % base;
                b /= base;
            } while(b);
            p[sz] *= fu;//标记符号 
            return *this;
        }
        HighPrecision operator + (const int &d){//重载+ (int)
            LL x = d;

            int fu = 1;//符号判断 
            HighPrecision c;
            if (p[sz] < 0 && x < 0) p[sz] *= -1, x *= -1, fu = -1;
            else if (p[sz] < 0) {p[sz] *= -1; return (c = x) - *this;}
            else if (x < 0) {x *= -1; return *this - x;}

            for (int i = 1; i <= sz && x; ++i) {//进位计算 
                x = x + p[i];
                p[i] = x % base;
                x = x / base;
            }
            if (x) p[++sz] = x;//进位 位数+1 
            p[sz] *= fu;
            return *this;
        }   
        HighPrecision operator + (const LL &d){//重载+ (long long)
            LL x = d;

            int fu = 1;//符号判断 
            HighPrecision c;
            if (p[sz] < 0 && x < 0) p[sz] *= -1, x *= -1, fu = -1;
            else if (p[sz] < 0) {p[sz] *= -1; return (c = x) - *this;}
            else if (x < 0) {x *= -1; return *this - x;}

            for (int i = 1; i <= sz && x; ++i) {//进位计算 
                x = x + p[i];
                p[i] = x % base;
                x = x / base;
            }
            if (x) p[++sz] = x;//进位 位数+1 
            p[sz] *= fu;
            return *this;
        }   
        HighPrecision operator + (const HighPrecision &d){//重载+ (HighPrecision)
            HighPrecision c, a = *this, b = d;

            int fu = 1;//符号判断 
            if (a.p[a.sz] < 0 && b.p[b.sz] < 0) a.p[a.sz] *= -1, b.p[b.sz] *= -1, fu = -1;
            else if (a.p[a.sz] < 0) {a.p[a.sz] *= -1; return b - a;}
            else if (b.p[b.sz] < 0) {b.p[b.sz] *= -1; return a - b;}

            if (a < b) a.swap(b);//a为大值,方便计算 
            if (b.sz < 3) {c = a + b.toLL(); c.p[c.sz] *= fu; return c;}//节省时间 
            LL x = 0;
            for(int i = 1; i <= a.sz; ++i) {
                x = x + a.p[i] + b.p[i];
                c.p[i] = x % base;
                x = x / base; 
            } 
            c.sz = a.sz;
            if (x) c.p[++c.sz] = x;//进位 位数+1 
            c.p[c.sz] *= fu;//标记符号 
            return c;
        }
        HighPrecision operator - (const HighPrecision &d){//重载- (HighPrecision)
            HighPrecision a = *this, c, b = d;

            int fu = 1;//符号判断 
            if(a.p[a.sz] < 0 && b.p[b.sz] < 0) a.p[a.sz] *= -1, b.p[b.sz] *= -1, fu *= -1;
            else if (a.p[a.sz] < 0) {a.p[a.sz] *= -1;c = a + b; c.p[c.sz] *= -1; return c;}
            else if (b.p[b.sz] < 0) {b.p[b.sz] *= -1; return a + b;}  

            LL x = 1, k = 0;
            if(a<b) a.swap(b), fu *= -1;
            if(a == b)return c = 0;//特殊情况直接输出 
            for(int i = 1; i <= a.sz; ++i){//借位计算 
                x = x + a.p[i] + base -1 - b.p[i]; 
                c.p[i] = x % base;
                x = x / base;   
            }
            for(c.sz = a.sz; c.p[c.sz] == 0; --c.sz);//计算c.sz 
            c.p[c.sz] *= fu;//符号标记 
            return c;
        }
        HighPrecision operator - (const int &d){//重载- (int)
            HighPrecision c;
            int b = d;

            int fu = 1;//符号判断 
            if(p[sz] < 0 && b < 0) p[sz] *= -1, b *= -1, fu *= -1;
            else if (p[sz] < 0) {p[sz] *= -1;c = *this + b; c.p[c.sz] *= -1; return c;}
            else if (b < 0) {b *= -1; return *this + b;}

            c=*this - (c = b);
            c.p[c.sz] *= fu;//符号标记 
            return c;
        }
        HighPrecision operator - (const LL &d){//重载- (long long)
            HighPrecision c;
            LL b = d;

            int fu = 1;//符号判断 
            if(p[sz] < 0 && b < 0) p[sz] *= -1, b *= -1, fu *= -1;
            else if (p[sz] < 0) {p[sz] *= -1;c = *this + b; c.p[c.sz] *= -1; return c;}
            else if (b < 0) {b *= -1; return *this + b;}

            c=*this - (c = b);
            c.p[c.sz] *= fu;//符号标记 
            return c;
        }
        HighPrecision operator * (const int &d){//重载* (int)
            HighPrecision a=*this,c;
            int b = d;

            int fu = 1;//符号判断 
            if(a.p[a.sz] < 0) a.p[a.sz] *= -1, fu *= -1; 
            if(b < 0) b *= -1, fu *= -1;

            LL x = 0;
            if(b == 0||a.sz == 1 && a.p[a.sz] == 0) return c = 0;
            for(int i = 1; i <= a.sz; ++i){
                x = x + 1ll * a.p[i] * b;
                c.p[i] = x % base;
                x = x / base;
            }
            c.sz = a.sz;//计算c.sz 
            for(; x; x /= base){
                c.p[++c.sz] = x % base;
            }   
            c.p[c.sz] *= fu;//符号标记 
            return c;
        } 
        HighPrecision operator * (const HighPrecision &d){//重载* (HighPrecision)
            HighPrecision a =* this, b = d, c;

            int fu = 1;//符号判断 
            if(a.p[a.sz] < 0) a.p[a.sz] *= -1, fu *= -1; 
            if(b.p[b.sz] < 0) b.p[b.sz] *= -1, fu *= -1;

            if(a < b) a.swap(b);
            if(b.sz < 2) return a * b.toLL(fu);
            if(b.sz == 1 && b.p[b.sz] == 0) return c = 0;
            LL x=0;

            for (int i = 1; i < a.sz + b.sz || x; ++i){//按位依次求出 
                int l = 1, r = b.sz, k = i;
                if (i <= b.sz) r = i;
                if (i >  a.sz) l = i - a.sz + 1, k = a.sz;
                for(int j = l; j <= r; ++j, --k){
                    x += 1ll * a.p[k] * b.p[j]; //注意数值范围 
                }
                c.p[++c.sz] = x % base;
                x = x / base;
            }
            c.p[c.sz] *= fu;//符号标记 
            return c;
        } 
        HighPrecision operator * (const LL &d){//重载* (long long)
            HighPrecision a=*this,c;
            LL b=d;

            int fu = 1;//符号判断 
            if(a.p[a.sz] < 0) a.p[a.sz] *= -1, fu *= -1; 
            if(b < 0) b *= -1, fu *= -1;

            if(d > 2e9) return a * (c = d);
            LL x = 0;
            if(b == 0||a.sz == 1 && a.p[a.sz] == 0) return c = 0;
            for(int i = 1; i <= a.sz; ++i){
                x = x + 1ll * a.p[i] * b;
                c.p[i] = x % base;
                x = x / base;
            }
            c.sz = a.sz;//计算c.sz 
            for(; x; x /= base){
                c.p[++c.sz] = x%base;
            }   
            c.p[c.sz] *= fu; //符号标记 
            return c;
        }
        HighPrecision operator / (const int &d){//重载/ (int) 
            HighPrecision a=*this, c;
            int b=d;

            int fu = 1;//判断符号
            if (a.p[a.sz] < 0) a.p[a.sz] *= -1, fu *= -1;
            if (b < 0) b *= -1, fu *= -1; 

            LL x=0;
            if (b == 0) return c;//除数为零 抛出异常状况 
            for(int i = a.sz; i; --i){
                x = x * base + a.p[i];
                c.p[i] = x / b;
                x = x % b;
            } 
            for(c.sz = a.sz; c.p[c.sz] == 0 && c.sz > 1; --c.sz);
            c.p[c.sz] *= fu; //符号标记 
            return c;
        }
        HighPrecision operator / (const LL &d){//重载/ (long long)
            HighPrecision a=*this, c;
            LL b=d;

            int fu = 1;//判断符号
            if (a.p[a.sz] < 0) a.p[a.sz] *= -1, fu *= -1;
            if (b < 0) b *= -1, fu *= -1; 

            LL x=0;
            if (b == 0) return c;//除数为零 抛出异常状况 
            for(int i = a.sz; i; --i){
                x = x * base + a.p[i];
                c.p[i] = x / b;
                x = x % b;
            } 
            for(c.sz = a.sz; c.p[c.sz] == 0 && c.sz > 1; --c.sz); 
            c.p[c.sz] *= fu;//符号标记 
            return c;
        }
        HighPrecision operator / (const HighPrecision &d){//重载/ (HighPrecision) 
            HighPrecision a=*this,b=d,c,ce; 

            int fu = 1;//判断符号
            if (a.p[a.sz] < 0) a.p[a.sz] *= -1, fu *= -1;
            if (b.p[b.sz] < 0) b.p[b.sz] *= -1, fu *= -1; 

            if(b.sz == 1 && b.p[b.sz] == 0) return c;//除数为零 抛出异常状况 
            if (a <  b) return c = 0;//被除数小于除数 
            if (a == b) return c = 1;//被除数等于除数 
            if (b.sz < 2) return a / b.toLL(fu);
            for(int i = a.sz; i; --i){
                for(int j = ++ce.sz; j > 1; --j)//模拟进位 
                    ce.p[j] = ce.p[j-1];
                ce.p[1] = a.p[i];
                if (ce < b) continue;//商为零 直接跳过 
                int l = 0, r = base, x;
                while(l <= r) {//二分查找商 
                    int mid = l + r >> 1; 
                    if (b  * mid <= ce) {
                        x = mid;
                        l = mid + 1;
                    }
                    else {
                        r = mid - 1; 
                    }
                } 
                c.p[i] = x; 
                ce = ce - b * x;
            }
            for(c.sz = a.sz; c.p[c.sz] == 0 && c.sz > 1; --c.sz);
            c.p[c.sz] *= fu; //符号标记 
            return c;
        }
        HighPrecision operator % (const int &d){//重载% (int) 
            HighPrecision a=*this, c;
            int b=d;

            int fu = 1;//判断符号
            if (a.p[a.sz] < 0) a.p[a.sz] *= -1, fu *= -1;
            if (b < 0) b *= -1, fu *= -1; 

            LL x=0;
            if (d == 0) return c;//除数为零 抛出异常状况 
            for(int i = a.sz; i; --i){
                x = (x * base + a.p[i]) % b;
            } 
            return c = x * fu;
        }
        HighPrecision operator % (const LL &d){//重载% (long long)
            HighPrecision a=*this, c;
            LL b=d;

            int fu = 1;//判断符号
            if (a.p[a.sz] < 0) a.p[a.sz] *= -1, fu *= -1;
            if (b < 0) b *= -1, fu *= -1; 

            LL x=0;
            if (d == 0) return c;//除数为零 抛出异常状况 
            for(int i = a.sz; i; --i){
                x = (x * base + a.p[i]) % b;
            } 
            return c = x * fu;
        }
        HighPrecision operator % (const HighPrecision &d){//重载% (HighPrecision) 
            HighPrecision a=*this,b=d,ce; 

            int fu = 1;//判断符号
            if (a.p[a.sz] < 0) a.p[a.sz] *= -1, fu *= -1;
            if (b.p[b.sz] < 0) b.p[b.sz] *= -1, fu *= -1; 

            if (b.sz == 1 && b.p[b.sz] == 0) return ce;//除数为零 抛出异常状况 
            if (a <  b) return a;//被除数小于除数 
            if (a == b) return ce = 0;//被除数等于除数 
            if (b.sz < 2) return a % b.toLL(fu);
            for(int i = a.sz; i; --i){
                if (!(ce.sz == 1 && ce.p[ce.sz] == 0))
                    for(int j = ++ce.sz; j > 1; --j)//模拟进位 
                        ce.p[j] = ce.p[j-1];
                ce.p[1] = a.p[i];
                if (ce < b) continue;//商为零 直接跳过 
                int l = 0, r = base, x;
                while(l <= r) {//二分查找商 
                    int mid = l + r >> 1;
                    if (ce < b * mid) {
                        r = mid - 1;
                    }
                    else {
                        x = mid;
                        l = mid + 1; 
                    }
                } 
                ce = ce - b * x;
            } 
            ce.p[ce.sz] *= fu; //符号标记 
            return ce;
        }
    public://区域三: 
        HighPrecision operator += (int &b) {return *this = *this + b;}
        HighPrecision operator -= (int &b) {return *this = *this - b;}
        HighPrecision operator *= (int &b) {return *this = *this * b;}
        HighPrecision operator /= (int &b) {return *this = *this / b;}
        HighPrecision operator %= (int &b) {return *this = *this % b;}
        HighPrecision operator += (LL  &b) {return *this = *this + b;}
        HighPrecision operator -= (LL  &b) {return *this = *this - b;}
        HighPrecision operator *= (LL  &b) {return *this = *this * b;}
        HighPrecision operator /= (LL  &b) {return *this = *this / b;}
        HighPrecision operator %= (LL  &b) {return *this = *this % b;}
        HighPrecision operator += (HighPrecision &b) {return *this = *this + b;}
        HighPrecision operator -= (HighPrecision &b) {return *this = *this - b;}
        HighPrecision operator *= (HighPrecision &b) {return *this = *this * b;}
        HighPrecision operator /= (HighPrecision &b) {return *this = *this / b;}
        HighPrecision operator %= (HighPrecision &b) {return *this = *this % b;}
        bool operator <  (const int &b) const {HighPrecision c;return *this <  (c=b);}
        bool operator <= (const int &b) const {HighPrecision c;return *this <= (c=b);}
        bool operator >  (const int &b) const {HighPrecision c;return *this >  (c=b);}
        bool operator >= (const int &b) const {HighPrecision c;return *this >= (c=b);}
        bool operator == (const int &b) const {HighPrecision c;return *this == (c=b);}
        bool operator != (const int &b) const {HighPrecision c;return *this != (c=b);}
        bool operator <  (const LL  &b) const {HighPrecision c;return *this <  (c=b);}
        bool operator <= (const LL  &b) const {HighPrecision c;return *this <= (c=b);}
        bool operator >  (const LL  &b) const {HighPrecision c;return *this >  (c=b);}
        bool operator >= (const LL  &b) const {HighPrecision c;return *this >= (c=b);}
        bool operator == (const LL  &b) const {HighPrecision c;return *this == (c=b);}
        bool operator != (const LL  &b) const {HighPrecision c;return *this != (c=b);}
        bool operator == (const HighPrecision &b) const {if(sz^b.sz)return false;
            for (int     i=sz;i;i--) if(p[i] ^ b.p[i]) return false;         return true ;}
        bool operator != (const HighPrecision &b) const {if(sz^b.sz)return true ;
            for (int     i=sz;i;i--) if(p[i] ^ b.p[i]) return true ;         return false;}
        bool operator <  (const HighPrecision &b) const {if(sz^b.sz)return sz<b.sz;
            for (int     i=sz;i;i--) if(p[i] ^ b.p[i]) return p[i] < b.p[i]; return false;}
        bool operator <= (const HighPrecision &b) const {if(sz^b.sz)return sz<b.sz;
            for (int     i=sz;i;i--) if(p[i] ^ b.p[i]) return p[i] < b.p[i]; return true ;}
        bool operator >  (const HighPrecision &b) const {if(sz^b.sz)return sz>b.sz;
            for (int     i=sz;i;i--) if(p[i] ^ b.p[i]) return p[i] > b.p[i]; return false;}
        bool operator >= (const HighPrecision &b) const {if(sz^b.sz)return sz>b.sz;
            for (int     i=sz;i;i--) if(p[i] ^ b.p[i]) return p[i] > b.p[i]; return true ;}     
    public://区域四:
        HighPrecision() {clear();}//重载构造函数 
        HighPrecision(int x) {*this = x;}
        HighPrecision(LL  x) {*this = x;} 
        void clear() {sz = 0; memset(p, 0, sizeof(p));}//清空函数 
        void swap(HighPrecision &b) {HighPrecision c = *this; *this = b; b = c;}//交换函数 
        LL toLL(int fu = 1) {//化值函数 
            LL x = 0;
            if (p[sz] < 0) 
                p[sz] *= -1, fu = -1;
            for(int i=sz;i;--i)
                x=x*base+p[i];
            return x * fu;
        }

    public:
        bool check(){//判偶数
            if(p[1]&1)return 0;
            return 1;
        }

//区域一:输入输出 、区域二:四则运算 、区域三:基础配置 、区域四:辅助函数 
} a, b;

string 函数

#include <iostream>
#include <string>
using namespace std;

int cmp(string, string);
string add(string, string);
string sub(string, string);
string mul(string, string);
string div(string, string);
string mod(string, string);

int main()
{
std:
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    string a, b;
    cin >> a >> b;
    cout << add(a, b) << "\n"
         << sub(a, b) << "\n"
         << mul(a, b) << "\n"
         << div(a, b) << "\n"
         << mod(a, b) << "\n";
    return 0;
}

int cmp(string str1, string str2)
{
    if (str1.length() < str2.length())
        return -1;
    if (str1.length() > str2.length())
        return 1;
    return str1.compare(str2);
}

string add(string str1, string str2)
{
    string str = "";
    int str1_len = str1.length(), str2_len = str2.length(), temp = 0;
    bool carry = 0;
    if (str1_len < str2_len)
        for (int i = 1; i <= str2_len - str1_len; i++)
            str1 = '0' + str1;
    else
        for (int i = 1; i <= str1_len - str2_len; i++)
            str2 = '0' + str2;
    str1_len = str1.length(), str2_len = str.length();
    for (int i = str1_len - 1; i >= 0; i--)
    {
        temp = str1[i] - '0' + str2[i] - '0' + carry;
        carry = temp / 10;
        temp %= 10;
        str = char(temp + '0') + str;
    }
    if (carry == 1)
        str = '1' + str;
    return str;
}

string sub(string str1, string str2)
{
    string str = "";
    int str1_len = str1.length(), str2_len = str2.length(), temp = 0;
    bool carry = 0;
    if (str1_len < str2_len)
        for (int i = 1; i <= str2_len - str1_len; i++)
            str1 = '0' + str1;
    else
        for (int i = 1; i <= str1_len - str2_len; i++)
            str2 = '0' + str2;
    str1_len = str1.length(), str2_len = str2.length();
    for (int i = str1_len - 1; i >= 0; i--)
    {
        temp = (str1[i] - '0') - (str2[i] - '0') - carry;
        if (temp < 0)
        {
            carry = 1;
            temp += 10;
        }
        else
            carry = 0;
        str = char(temp + '0') + str;
    }
    str.erase(0, str.find_first_not_of('0'));
    if (str.empty())
        str = "0";
    return str;
}

string mul(string str1, string str2)//注意!有锅!请用上面的!
{
    string str = "", temp_num = "";
    int carry = 0, temp_digit = 0;
    int str1_len = str1.length(), str2_len = str2.length();
    for (int i = str2_len - 1; i >= 0; i--)
    {
        temp_num = "";
        temp_num.insert(0, str2_len - 1 - i, '0');
        for (int j = str1_len - 1; j >= 0; j--)
        {
            temp_digit = (str2[i] - '0') * (str1[j] - '0') + carry;
            carry = temp_digit / 10;
            temp_digit %= 10;
            temp_num = char(temp_digit + '0') + temp_num;
        }
        if (carry != 0)
            temp_num = char(carry + '0') + temp_num;
        str = add(str, temp_num);
    }
    str.erase(0, str.find_first_not_of('0'));
    if (str.empty())
        str = "0";
    return str;
}

string div(string str1, string str2)
{
    string str = "";
    int str1_len = str1.length(), str2_len = str2.length();
    if (str2 == "0")
        str = "ERROR";
    else if (str1 == "0")
        str = "0";
    else if (cmp(str1, str2) < 0)
        str = "0";
    else if (cmp(str1, str2) == 0)
        str = "1";
    else
    {
        string dividend = "";
        dividend.append(str1, 0, str2_len - 1);
        for (int i = str2_len - 1; i < str1_len; i++)
        {
            dividend += str1[i];
            dividend.erase(0, dividend.find_first_not_of('0'));
            if (dividend.empty())
                dividend = "0";
            for (char ch = '9'; ch >= '0'; ch--)
            {
                string tempstr;
                tempstr += ch;
                string temp = mul(str2, (tempstr));
                if (cmp(temp, dividend) <= 0)
                {
                    str += ch;
                    dividend = sub(dividend, temp);
                    break;
                }
            }
        }
        str.erase(0, str.find_first_not_of('0'));
        if (str.empty())
            str = "0";
    }
    return str;
}

string mod(string str1, string str2)
{
    string str;
    if (str2 == "0")
        str = "ERROR";
    str = sub(str1, mul(div(str1, str2), str2));
    return str;
}

高精GCD

//依赖上面的高精度

HighPrecision gcd(HighPrecision a,HighPrecision b){//小心爆栈哦
    HighPrecision r=1;
    while(b!=0){
        if(a<b)swap(a,b);
        // a.cout(),b.cout(1);
        if(a.check()&&b.check()){
            a=a/2;
            b=b/2;
            r=r*2;
        }
        else if(a.check()){a=a/2;}
        else if(b.check()){b=b/2;}//多打括号&cmr
        else a-=b;
    }
    return a*r;
}

FFT高精度

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define cp complex <double>
const int N=10000005;
const double PI=acos(-1);
int n=1,la,lb,res[N*2];
cp a[N],b[N],omg[N],inv[N];
char sa[N],sb[N];

void init(){
    for(int i=0;i<n;i++){
        omg[i]=cp(cos(2*PI*i/n),sin(2*PI*i/n));
        inv[i]=conj(omg[i]);
    }
}

void fft(cp *a,cp *omg){
    int lim =0;
    while((1<<lim)<n)lim++;
    for(int i=0;i<n;i++){
        int t=0;
        for(int j=0;j<lim;j++)if((i>>j)&1)t|=(1<<(lim-j-1));
        if(i<t)swap(a[i],a[t]);
    }
    for(int l=2;l<=n;l*=2){
        int m=l/2;
        for(cp *p=a;p!=a+n;p+=l)for(int i=0;i<m;i++){
            cp t=omg[n/l*i]*p[i+m];
            p[i+m]=p[i]-t;
            p[i]+=t;
        }
    }
}
signed main(){
    //freopen("P1919_1.in","r",stdin);
    scanf("%s%s",&sa,&sb);
    la=strlen(sa),lb=strlen(sb);

    while(n<la+lb)n*=2;
    for(int i=0;i<la;i++)a[i].real(sa[la-1-i]-'0');
    for(int i=0;i<lb;i++)b[i].real(sb[lb-1-i]-'0');

    init();

    fft(a,omg);
    fft(b,omg);

    for(int i=0;i<n;i++){
        a[i]*=b[i];
    }

    fft(a,inv);

    for(int i=0;i<n;i++){
        res[i]+=floor(a[i].real()/n+0.5);
        res[i+1]+=res[i]/10;
        res[i]%=10;
    }
    int l=la+lb-1;
    if(!res[la+lb-1])l--;
    for(int i=l;i>=0;i--)putchar('0'+res[i]);

    return 0;
}