• C++
  • GESP/信奥专用 C++ 高精度加减乘除 全套竞赛教程

  • @ 2026-7-31 20:16:16

GESP/信奥专用 C++ 高精度加减乘除 全套竞赛教程

前言(竞赛考纲定位)

C++ 普通 int、long long 数据类型有固定数值上限,无法存储几十位、上百位的超大整数。高精度算法通过数组模拟人工竖式运算,解决超大整数运算问题,是 GESP4级必考、CSP-J 入门高频考点

本教程为纯应试版本,无冗余知识点,提供可直接默写的满分模板、统一编码规范、考场避坑要点、经典真题题型,适配所有信奥入门考试。

一、高精度核心基础(必学规范)

1. 为什么要用数组模拟?

int 最大约 2e9(10位),long long 最大约 9e18(19位),竞赛题目常出现 50位、100位、1000位超大整数,原生数据类型无法存储,必须用数组逐位存储数字。

2. 竞赛统一存储规则(重中之重)

所有高精度运算统一采用 低位存在数组下标0 的倒存方式,适配所有加减乘除运算,统一逻辑、减少出错:

  • 例:数字 1234,数组存储为:a[0]=4,a[1]=3,a[2]=2,a[3]=1
  • 优势:进位、借位从低位开始计算,无需频繁移位,代码极简

3. 通用预处理函数(所有运算通用)

字符串转高精度数组、获取数字长度,所有模板统一调用,考场直接复用:

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

const int N = 1005; // 适配1000位以内大数,GESP、CSP-J足够

// 字符串转高精度数组(倒存)
void strToInt(string s, int a[], int &len)
{
    len = s.size();
    for(int i = 0; i < len; i++)
    {
        a[i] = s[len - 1 - i] - '0';
    }
}

// 输出高精度数组(自动正序输出)
void print(int a[], int len)
{
    for(int i = len - 1; i >= 0; i--)
    {
        cout << a[i];
    }
    cout << endl;
}

二、高精度加法(GESP 基础必考)

1. 运算原理

模拟竖式加法:从低位到高位逐位相加,保留个位,进位存入下一位,最终处理最高位进位。

2. 考场满分模板

// 高精度加法:a + b,结果存入c
void add(int a[], int la, int b[], int lb, int c[], int &lc)
{
    lc = 0;
    int carry = 0; // 进位
    // 逐位相加,遍历最长数字长度+剩余进位
    while(lc < la || lc < lb || carry)
    {
        int sum = carry;
        if(lc < la) sum += a[lc];
        if(lc < lb) sum += b[lc];
        c[lc] = sum % 10; // 当前位结果
        carry = sum / 10; // 更新进位
        lc++;
    }
}

// 完整可运行示例
int main()
{
    string s1, s2;
    cin >> s1 >> s2;
    int a[N], b[N], c[N];
    int la, lb, lc;
    strToInt(s1, a, la);
    strToInt(s2, b, lb);
    add(a, la, b, lb, c, lc);
    print(c, lc);
    return 0;
}

3. 易错点

  • 必须遍历到 进位为0,避免最高位进位丢失
  • 无需手动对齐位数,代码自动适配长短数字

三、高精度减法(GESP 进阶必考)

1. 运算规则

仅支持 大减小(竞赛题目默认保证,代码内置比较函数),模拟竖式借位减法,低位不够向高位借1当10。

2. 辅助比较函数(必备)

// 比较两个高精度数大小:a>b返回true,否则false
bool cmp(int a[], int la, int b[], int lb)
{
    if(la != lb) return la > lb;
    for(int i = la - 1; i >= 0; i--)
    {
        if(a[i] != b[i]) return a[i] > b[i];
    }
    return true; // 两数相等
}

3. 考场满分模板

// 高精度减法:a - b (保证a >= b)
void sub(int a[], int la, int b[], int lb, int c[], int &lc)
{
    lc = la;
    int borrow = 0; // 借位
    for(int i = 0; i < lc; i++)
    {
        // 当前位减借位,再减对应b的位
        int now = a[i] - borrow;
        if(i < lb) now -= b[i];
        if(now < 0) // 不够减,借位
        {
            now += 10;
            borrow = 1;
        }
        else borrow = 0;
        c[i] = now;
    }
    // 去除前导零(核心!否则输出错误)
    while(lc > 1 && c[lc - 1] == 0) lc--;
}

// 完整可运行示例
int main()
{
    string s1, s2;
    cin >> s1 >> s2;
    int a[N], b[N], c[N];
    int la, lb, lc;
    strToInt(s1, a, la);
    strToInt(s2, b, lb);
    
    if(cmp(a, la, b, lb))
    {
        sub(a, la, b, lb, c, lc);
        print(c, lc);
    }
    else
    {
        cout << "-";
        sub(b, lb, a, la, c, lc);
        print(c, lc);
    }
    return 0;
}

4. 超级易错点

  • 减法必须 去前导零,否则会出现 00123 错误输出
  • 需要判断大小,负数需手动输出负号

四、高精度乘法(CSP-J 高频)

1. 运算原理

模拟竖式乘法:逐位相乘,错位累加至对应位置,全部计算完成后统一处理进位,相比逐位进位写法更简洁、容错率更高。

2. 考场满分模板

// 高精度乘法:a * b
void mul(int a[], int la, int b[], int lb, int c[], int &lc)
{
    // 初始化结果数组为0
    fill(c, c + N, 0);
    for(int i = 0; i < la; i++)
    {
        for(int j = 0; j < lb; j++)
        {
            c[i + j] += a[i] * b[j]; // 错位累加
        }
    }
    // 统一处理进位
    lc = la + lb;
    for(int i = 0; i < lc; i++)
    {
        c[i + 1] += c[i] / 10;
        c[i] = c[i] % 10;
    }
    // 去除前导零
    while(lc > 1 && c[lc - 1] == 0) lc--;
}

// 完整可运行示例
int main()
{
    string s1, s2;
    cin >> s1 >> s2;
    int a[N], b[N], c[N];
    int la, lb, lc;
    strToInt(s1, a, la);
    strToInt(s2, b, lb);
    mul(a, la, b, lb, c, lc);
    print(c, lc);
    return 0;
}

3. 核心考点

  • 两个n位、m位数字相乘,结果最大长度为 n+m
  • 先累加、后统一进位,代码更简洁,不易出错

五、高精度除法(GESP4级压轴、CSP-J难点)

竞赛入门仅考 高精度大数 ÷ 低精度整数(高精度÷高精度极少考),提供应试专用模板,支持求商、求余。

1. 考场满分模板(高精度 / 普通整数)

// 高精度除法:a / b(低精度int),返回余数,商存入c
int div(int a[], int la, int b, int c[], int &lc)
{
    lc = 0;
    int rem = 0; // 余数
    // 从高位到低位计算(除法唯一正序遍历)
    for(int i = la - 1; i >= 0; i--)
    {
        rem = rem * 10 + a[i];
        c[lc++] = rem / b;
        rem = rem % b;
    }
    // 反转数组,统一低位倒存规则
    reverse(c, c + lc);
    // 去前导零
    while(lc > 1 && c[lc - 1] == 0) lc--;
    return rem;
}

// 完整可运行示例
int main()
{
    string s;
    int b;
    cin >> s >> b;
    int a[N], c[N];
    int la, lc;
    strToInt(s, a, la);
    int rem = div(a, la, b, c, lc);
    print(c, lc);
    cout << "余数:" << rem << endl;
    return 0;
}

2. 关键特性

  • 除法唯一需要 从高位向低位 遍历,与加减乘运算遍历方向相反
  • 模板自带余数返回,适配所有求商、求余真题

六、GESP/信奥 考场通用避坑大全

  1. 存储规则统一:全程低位倒存,禁止混用存储方式,所有模板通用适配
  2. 前导零必删:减法、乘法、除法必须去前导零,加法无前置零问题,无需处理
  3. 数组初始化:乘法务必清空数组,避免历史脏数据干扰计算结果
  4. 边界判断:去前导零时保留最后一位非零数,避免结果0被清空无输出
  5. 除法特殊逻辑:唯一正序遍历运算,计算后需反转数组,统一全局倒存格式

七、真题适配题型

  • GESP3级:高精度大数加法、基础减法运算题
  • GESP4级:高精度乘法、大数除法、带余数运算、分数化简
  • CSP-J:高精度四则混合运算、大数阶乘、大数幂运算、高精度模拟应用题

2 条评论

  • @ 2026-7-31 20:17:05

    C++ 数组模拟高精度四则运算 零基础完整教程

    前置知识说明

    为什么需要高精度?

    C++ 内置类型:intlong long 存储数字范围有限。 long long 最大只能存 9e18,超过这个大小就会溢出。 高精度:用数组存储超大整数的每一位,手动模拟竖式加减乘除。

    统一约定(全部代码遵守)

    1. 数字逆序存在数组(低位在下,数组下标0存个位) 例:数字 1234 → 数组:a[0]=4, a[1]=3, a[2]=2, a[3]=1 ✅ 好处:进位直接往后放,不用移动大量元素
    2. len:记录当前数字有效位数
    3. 全部只处理非负大整数(零基础先不学负数,减法单独处理大小比较)
    4. 数组大小统一开 1005,足够日常练习;需要更大自行调大

    逆序示意图 数字: 1 2 3 4 下标: [3][2][1][0] 位值:千 百 十 个


    一、高精度加法(A+B)

    竖式规则:从个位相加,满10进1

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int MAXN = 1005;
    
    // 高精度加法 a + b = c
    void add(int a[], int la, int b[], int lb, int c[], int &lc)
    {
        // carry = 进位
        int carry = 0;
        // 最长数字的位数循环
        lc = max(la, lb);
        for(int i = 0; i < lc; i++)
        {
            // 当前位 = a当前位 + b当前位 + 进位
            int sum = a[i] + b[i] + carry;
            c[i] = sum % 10;    // 当前保留个位
            carry = sum / 10;   // 算出新进位
        }
        // 如果最后还有进位,多增加一位
        if(carry != 0)
        {
            c[lc] = carry;
            lc++;
        }
    }
    
    // 字符串转逆序数组
    void str_to_arr(string s, int num[], int &len)
    {
        len = s.size();
        for(int i = 0; i < len; i++)
        {
            // s[0]是最高位,放到数组尾部,逆序存储
            num[len - 1 - i] = s[i] - '0';
        }
    }
    
    // 输出逆序数组
    void print_arr(int num[], int len)
    {
        // 逆序打印,从最高位输出
        for(int i = len - 1; i >= 0; i--)
            cout << num[i];
        cout << endl;
    }
    
    int main()
    {
        int a[MAXN] = {0}, la;
        int b[MAXN] = {0}, lb;
        int c[MAXN] = {0}, lc;
    
        string s1, s2;
        cin >> s1 >> s2;
    
        str_to_arr(s1, a, la);
        str_to_arr(s2, b, lb);
    
        add(a, la, b, lb, c, lc);
        print_arr(c, lc);
        return 0;
    }
    

    测试输入:

    9999
    1
    

    输出:10000


    二、高精度减法(A-B,要求 A≥B)

    竖式规则:从个位相减,不够减向前一位借1当10

    使用前必须先判断大小!如果A<B,结果是负数,零基础简化版只实现大数减小数

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int MAXN = 1005;
    
    // 比较两个高精度数:a>=b 返回true
    bool cmp(int a[], int la, int b[], int lb)
    {
        // 位数长的数字更大
        if(la != lb) return la > lb;
        // 位数相同,从最高位依次比较
        for(int i = la - 1; i >= 0; i--)
        {
            if(a[i] != b[i])
                return a[i] > b[i];
        }
        return true; // 两数相等
    }
    
    // 高精度减法 a-b,前提 a >= b
    void sub(int a[], int la, int b[], int lb, int c[], int &lc)
    {
        lc = la; // 结果最多和被减数位数一样
        int borrow = 0; // borrow 借位
        for(int i = 0; i < lc; i++)
        {
            // 当前位减去之前的借位
            int now = a[i] - borrow - b[i];
            borrow = 0;
            if(now < 0)
            {
                now += 10;
                borrow = 1; // 需要向高位借1
            }
            c[i] = now;
        }
        // 清除前导0(高位多余的0)
        while(lc > 1 && c[lc - 1] == 0)
            lc--;
    }
    
    void str_to_arr(string s, int num[], int &len)
    {
        len = s.size();
        for(int i = 0; i < len; i++)
            num[len - 1 - i] = s[i] - '0';
    }
    
    void print_arr(int num[], int len)
    {
        for(int i = len - 1; i >= 0; i--)
            cout << num[i];
        cout << endl;
    }
    
    int main()
    {
        int a[MAXN]={0}, la;
        int b[MAXN]={0}, lb;
        int c[MAXN]={0}, lc;
        string s1,s2;
        cin>>s1>>s2;
        str_to_arr(s1,a,la);
        str_to_arr(s2,b,lb);
    
        if(cmp(a,la,b,lb))
        {
            sub(a,la,b,lb,c,lc);
            print_arr(c,lc);
        }
        else
        {
            cout<<"-";
            sub(b,lb,a,la,c,lc);
            print_arr(c,lc);
        }
        return 0;
    }
    

    测试输入:

    1000
    999
    

    输出:1

    测试:123 456 → 输出 -333


    三、高精度乘法(A × B)

    竖式原理:a第i位 × b第j位 → 结果落在 i+j 位置

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int MAXN = 1005;
    
    void mul(int a[], int la, int b[], int lb, int c[], int &lc)
    {
        memset(c, 0, sizeof(c));
        // 双重循环模拟竖式每一位相乘
        for(int i = 0; i < la; i++)
        {
            int carry = 0;
            for(int j = 0; j < lb; j++)
            {
                // 原有数字 + a[i]*b[j] + 进位
                long long sum = c[i+j] + 1LL * a[i] * b[j] + carry;
                c[i+j] = sum % 10;
                carry = sum / 10;
            }
            // 剩余进位继续向后放
            if(carry != 0)
                c[i + lb] += carry;
        }
        // 最大位数 la+lb
        lc = la + lb;
        // 去除前导零
        while(lc > 1 && c[lc - 1] == 0)
            lc--;
    }
    
    void str_to_arr(string s, int num[], int &len)
    {
        len = s.size();
        for(int i = 0; i < len; i++)
            num[len - 1 - i] = s[i] - '0';
    }
    
    void print_arr(int num[], int len)
    {
        for(int i = len - 1; i >= 0; i--)
            cout << num[i];
        cout << endl;
    }
    
    int main()
    {
        int a[MAXN]={0}, la;
        int b[MAXN]={0}, lb;
        int c[MAXN]={0}, lc;
        string s1,s2;
        cin>>s1>>s2;
        str_to_arr(s1,a,la);
        str_to_arr(s2,b,lb);
        mul(a,la,b,lb,c,lc);
        print_arr(c,lc);
        return 0;
    }
    

    输入:9999 9999 输出:99980001

    注意:1LL * a[i] * b[j] 防止乘法溢出!


    四、高精度除法(大数 ÷ 普通整数,零基础首选)

    ⚠️ 高精度÷高精度逻辑极其复杂,初学先掌握:高精度大数 ÷ int 整数(竞赛最常用) 思路:从最高位往低位依次试商

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int MAXN = 1005;
    
    // a被除数,la长度;b除数(普通int);c商;rem余数
    void div(int a[], int la, int b, int c[], int &lc, long long &rem)
    {
        rem = 0;
        lc = 0;
        // 除法正向遍历!从最高位开始(和加减乘反过来)
        for(int i = la - 1; i >= 0; i--)
        {
            rem = rem * 10 + a[i];
            c[lc++] = rem / b; // 当前位商
            rem = rem % b;     // 更新余数
        }
        // c数组现在正向存储商,需要翻转!同时清除前导0
        int temp[MAXN] = {0}, tl = 0;
        bool flag = false;
        for(int i = 0; i < lc; i++)
        {
            if(c[i] == 0 && !flag)
                continue; // 跳过前导0
            flag = true;
            temp[tl++] = c[i];
        }
        // 特判结果为0
        if(tl == 0) tl = 1;
        // 逆序放回c,统一和加减乘格式保持一致
        memset(c, 0, sizeof(c));
        lc = tl;
        for(int i = 0; i < lc; i++)
            c[lc - 1 - i] = temp[i];
    }
    
    void str_to_arr(string s, int num[], int &len)
    {
        len = s.size();
        for(int i = 0; i < len; i++)
            num[len - 1 - i] = s[i] - '0';
    }
    
    void print_arr(int num[], int len)
    {
        for(int i = len - 1; i >= 0; i--)
            cout << num[i];
        cout << endl;
    }
    
    int main()
    {
        int a[MAXN]={0}, la;
        int c[MAXN]={0}, lc;
        long long rem;
        string s;
        int b;
        cin >> s >> b;
        str_to_arr(s,a,la);
        div(a, la, b, c, lc, rem);
        cout << "商:";
        print_arr(c, lc);
        cout << "余数:" << rem << endl;
        return 0;
    }
    

    输入:1234567890123456789 7 输出商和余数

    零基础学习路线建议

    1. 先看懂【逆序数组存储】核心思想
    2. 吃透高精度加法(进位逻辑)
    3. 学习减法(借位 + 大小比较)
    4. 学习乘法(双重循环)
    5. 学习高精度除普通整数
    6. 有余力再拓展【高精度 ÷ 高精度】

    通用函数总结(四个代码共用)

    • str_to_arr:字符串 → 逆序数字数组(输入)
    • print_arr:逆序数组 → 正常数字输出

    常见踩坑提醒

    1. 数组一定要初始化0! int a[MAXN]={0}
    2. 乘法容易溢出,相乘前强制转long long
    3. 减法、乘法记得删除前导零(比如 00123 → 123)
    4. 加法最后别忘记处理最后的进位
    • @ 2026-7-31 20:16:46

      C++ 高精度四则运算【0基础易懂教程】

      先搞懂核心概念

      普通变量局限: intlong long 能存的数字有限,如果数字长达几十位、上百位,存不下! 解决方案:用数组/vector保存每一位数字,手动模拟竖式笔算

      统一存储规则(四则全部通用,务必记住)

      低位存在数组前面(下标小的位置) 例:数字 123 = 百位1,十位2,个位3 存储方案:a[1]=3(个位),a[2]=2(十位),a[3]=1(百位) a[0] 专门存这个数字一共有多少位 → a[0]=3

      为什么倒着存? 计算产生进位时,直接往后面下标 i+1 写数字,不用整体挪动数组,写代码最简单!

      输入字符串 123 → 逆序放进数组 输出数组 → 从后往前打印


      工具函数(四个运算共用,先复制)

      #include <iostream>
      #include <vector>
      #include <string>
      using namespace std;
      
      // 函数1:字符串 → 高精度数组(低位在前)
      vector<int> str2big(string s)
      {
          vector<int> num;
          num.push_back(s.size()); // num[0] 存储位数
          // 字符串末尾是个位,倒着存入数组
          for(int i = s.size() - 1; i >= 0; i--)
          {
              num.push_back(s[i] - '0');
          }
          return num;
      }
      
      // 函数2:打印高精度数字
      void print(vector<int> num)
      {
          // 从高位往低位输出(数组尾部是高位)
          for(int i = num[0]; i >= 1; i--)
          {
              cout << num[i];
          }
          cout << endl;
      }
      
      // 函数3:比较两个高精度数大小 a >= b 返回true(减法、除法要用)
      bool compare(vector<int> a, vector<int> b)
      {
          // 位数长的数字更大
          if(a[0] != b[0]) return a[0] > b[0];
          // 位数相同,从高位逐一对比
          for(int i = a[0]; i >= 1; i--)
          {
              if(a[i] != b[i]) return a[i] > b[i];
          }
          return true; // 两个数相等
      }
      

      1. 高精度加法(a + b)

      笔算思路:个位开始相加,满10进1

      // 高精度加法 a + b
      vector<int> add(vector<int> a, vector<int> b)
      {
          vector<int> res;
          int carry = 0; // carry 进位,初始0
      
          // 只要还有位数没算完 或者 还有进位,继续循环
          for(int i = 1; i <= a[0] || i <= b[0] || carry; i++)
          {
              // 当前位累加,没有数字就默认加0
              if(i <= a[0]) carry += a[i];
              if(i <= b[0]) carry += b[i];
      
              res.push_back(carry % 10); // 当前位保留个位
              carry = carry / 10;        // 算出新的进位
          }
          res[0] = res.size(); // 记录总位数
          return res;
      }
      
      // 加法测试main
      /*
      int main()
      {
          string s1, s2;
          cin >> s1 >> s2;
          vector<int> a = str2big(s1);
          vector<int> b = str2big(s2);
          vector<int> ans = add(a,b);
          print(ans);
          return 0;
      }
      测试输入:123456 7890
      输出:131346
      */
      

      2. 高精度减法(a - b,支持负数结果)

      笔算思路:逐位相减,不够向前一位借1当10

      // 高精度减法 a - b  前提 a >= b
      vector<int> sub(vector<int> a, vector<int> b)
      {
          vector<int> res;
          int borrow = 0; // borrow 借位标记
      
          for(int i = 1; i <= a[0]; i++)
          {
              int cur = a[i] - borrow; // 先减去之前的借位
              if(i <= b[0]) cur -= b[i];
      
              if(cur < 0) // 不够减,需要借位
              {
                  cur += 10;
                  borrow = 1; // 标记需要向前借位
              }
              else
              {
                  borrow = 0;
              }
              res.push_back(cur);
          }
      
          // 删除高位多余前导0!例如1000-999得到0001 → 删掉前面0
          while(res.size() > 1 && res.back() == 0)
              res.pop_back();
      
          res[0] = res.size();
          return res;
      }
      
      // 减法完整测试main(自动判断正负)
      /*
      int main()
      {
          string s1, s2;
          cin >> s1 >> s2;
          vector<int> a = str2big(s1);
          vector<int> b = str2big(s2);
          vector<int> ans;
          if(compare(a,b))
          {
              ans = sub(a,b);
          }
          else
          {
              cout << "-"; // 结果负数
              ans = sub(b,a);
          }
          print(ans);
          return 0;
      }
      测试1:1000 999 → 1
      测试2:999 1000 → -1
      */
      

      3. 高精度乘法

      分两种: ① 大数 × 普通整数(竞赛高频,简单) ② 大数 × 大数(拓展)

      3.1 高精度 × 低精度(推荐初学先掌握)

      // 高精度数字 a * 普通整数x
      vector<int> mul_small(vector<int> a, int x)
      {
          vector<int> res;
          long long carry = 0; // 使用long long防止相乘溢出
      
          for(int i = 1; i <= a[0] || carry; i++)
          {
              if(i <= a[0])
                  carry += (long long)a[i] * x;
      
              res.push_back(carry % 10);
              carry /= 10;
          }
          // 清除前导0
          while(res.size() > 1 && res.back() == 0)
              res.pop_back();
          res[0] = res.size();
          return res;
      }
      
      /*
      main测试
      int main()
      {
          string s;
          int x;
          cin >> s >> x;
          vector<int> a = str2big(s);
          vector<int> ans = mul_small(a,x);
          print(ans);
      }
      输入:123456789 100
      输出:12345678900
      */
      

      3.2 高精度 × 高精度(大数×大数)

      vector<int> mul_big(vector<int> a, vector<int> b)
      {
          vector<int> res(a[0] + b[0], 0); // 预先分配最大长度
          // 双重循环模拟竖式
          for(int i = 1; i <= a[0]; i++)
          {
              long long carry = 0;
              for(int j = 1; j <= b[0] || carry; j++)
              {
                  if(j <= b[0])
                      carry += (long long)a[i] * b[j];
                  carry += res[i + j - 1];
                  res[i + j - 1] = carry % 10;
                  carry /= 10;
              }
          }
          // 删掉前导零
          while(res.size() > 1 && res.back() == 0)
              res.pop_back();
          res[0] = res.size() - 1;
          return res;
      }
      /*
      测试main
      int main()
      {
          string s1,s2;
          cin>>s1>>s2;
          auto a=str2big(s1),b=str2big(s2);
          auto ans=mul_big(a,b);
          print(ans);
      }
      输入:999 999  输出998001
      */
      

      4. 高精度 ÷ 低精度(初学优先掌握,返回商和余数)

      高精度÷高精度难度很高,新手先学【大数 ÷ 普通整数】 ⚠️ 除法和前面反过来!从高位开始计算

      // a / x  商存在quot,余数作为返回值
      long long div_small(vector<int> a, int x, vector<int>& quot)
      {
          quot.clear();
          long long rem = 0; // rem 余数
          // 除法从高位往低位算!倒着遍历
          for(int i = a[0]; i >= 1; i--)
          {
              rem = rem * 10 + a[i];
              quot.push_back(rem / x);
              rem = rem % x;
          }
          // 当前quot是高位在前,反转成【低位在前】统一格式
          reverse(quot.begin(), quot.end());
          // 清除前导0
          while(quot.size() > 0 && quot.back() == 0)
              quot.pop_back();
          // 特判商为0的情况
          if(quot.empty()) quot.push_back(0);
          quot.push_back(quot.size());
          swap(quot[0], quot.back()); // 把长度放到下标0
          return rem;
      }
      
      /*
      main测试
      int main()
      {
          string s;
          int x;
          cin >> s >> x;
          vector<int> a = str2big(s);
          vector<int> shang;
          long long yu = div_small(a, x, shang);
          cout << "商:";
          print(shang);
          cout << "余数:" << yu << endl;
      }
      输入:12345 7
      商:1763  余数4
      */
      

      完整整合说明

      1. 所有代码复制到同一个cpp文件即可运行
      2. 想测试哪个运算,就打开对应注释里的main函数,删掉其他main
      3. 学习顺序建议:加法 → 减法 → 大数乘小数 → 大数除小数 → 大数乘大数

      新手常见坑提醒

      1. ❌ 忘记清除前导0,输出一堆000123
      2. ❌ 乘法不用long long存进位,发生数据溢出
      3. ❌ 混淆高低位,加法减法低位在前,除法遍历顺序相反
      4. ❌ 借位、进位忘记初始化,循环出错
      • 1