GESP 五级 第 03 讲:高精度加减乘除

本讲定位:官方大纲里唯一标注”C++ 专属”的知识块——Python 自带大整数,不考这一块,C++ 必须手写。内容是纯模板题:理解了竖式笔算,代码就是把笔算过程翻译一遍。这一讲学生最容易”看懂但写不对”,所以本讲的重点是把每个边界条件抠死。

对应官方大纲:五级知识块 3「C++ 高精度运算」——数组模拟高精度加法、减法、乘法、除法。

前置知识:数组、字符串、五级第 01 讲的取模。

代码说明:本讲所有模板均已用 g++ 11.5 编译,并与 Python 的大整数运算随机对拍 1000 组验证通过(对拍脚本见 §8)。


1. 为什么需要高精度

C++ 内置整数类型有上限:

类型 上限 大约位数
int $2147483647$ 10 位
long long $9223372036854775807$ 19 位
unsigned long long $18446744073709551615$ 20 位

但题目可能要你算 $100!$(158 位)或两个 1000 位数相加。 这时只能用数组模拟人工笔算——这就是高精度。

📌 判断要不要用高精度:题目说”答案可能很大”且没有让你取模,基本就是高精度题。(如果让取模,那就用五级第 01 讲的模运算,不用高精度。)


2. 存储方式:倒序存储

2.1 为什么要倒序

把数字 $12345$ 存进数组,有两种方式:

正序:a[0]=1, a[1]=2, a[2]=3, a[3]=4, a[4]=5     ← 直觉,但麻烦
倒序:a[0]=5, a[1]=4, a[2]=3, a[3]=2, a[4]=1     ← 标准做法 ✅

倒序(低位在前)的三个好处:

  1. 加法进位是从低位往高位,倒序时就是从 a[0] 往后走,和数组下标增长方向一致
  2. 进位导致位数增加时,直接在数组末尾追加即可,不用整体挪动
  3. a[i] 就代表 $10^i$ 位,下标和数位权重直接对应。

$$ \boxed{\text{高精度一律倒序存储:a[i] 表示 } 10^i \text{ 位上的数字}} $$

2.2 读入与输出

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

const int MAXL = 5005;      // 最大位数

// 把字符串转成倒序数组,返回长度
int toArray(const string &s, int a[]) {
    int len = s.size();
    for (int i = 0; i < len; i++)
        a[i] = s[len - 1 - i] - '0';        // ★ 倒着放,字符转数字
    return len;
}

// 输出倒序数组
void print(int a[], int len) {
    while (len > 1 && a[len-1] == 0) len--; // ★ 去前导零(但至少保留一位)
    for (int i = len - 1; i >= 0; i--)      // 倒着输出
        cout << a[i];
    cout << endl;
}