💡 高精度是通过字符串 + 数组逆序存储模拟竖式计算,解决 C++ 内置类型(int/long long)无法存储和运算超大整数的方法,核心包含加减乘除四大基础运算。


1 通用基础

💡  字符串存大数、数组逆序拆分、结果逆序输出 

1.1 核心存储逻辑

  1. 超大数无法用 int/long long 存储,先存入string 字符串(x、y)
  2. 字符串不能直接运算,需逐字符转数字并逆序存入数组
    • 逆序原因:竖式计算从最低位开始,进位 / 借位时在数组尾部追加元素更方便,避免头部插入的复杂度
  3. 结果存储在数组 c 中,最终逆序输出(从高位到低位)

专业 📚

  1. C++ 内置整型范围:int(±2e9)、long long(±9e18),超过该范围的整数称为高精度数
  2. 逆序存储是高精度算法的行业标准方案,完美适配四则运算的进位 / 借位操作

拆分逆序核心代码 🧑💻

// 计算字符串长度
la = x.size();
lb = y.size();
lc = max(la, lb); // 结果长度初始值(加减除专用),乘法为 la+lb

// 逐字符转数字 + 逆序存入数组(核心代码)
for(int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';
for(int i = 0; i < lb; i++) b[lb - 1 - i] = y[i] - '0';

⚠️ 适用场景 & 核心注意

  • x[i] - '0' 是字符转数字的唯一标准方法(利用 ASCII 码差值)
  • 所有高精度运算必须先执行逆序拆分,无例外

1.2 必备头文件 & 全局变量

  1. 强制头文件:
    • <string>:存储高精度数
    • <algorithm>:调用 max 函数计算长度
    • <iostream>:标准输入输出
  2. 全局数组:必须开大空间(防止栈溢出),a/b 存运算数,c 存结果
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

const int N = 1e6 + 10; // 开大数组,避免越界
int a[N], b[N], c[N];   // a:第一个数  b:第二个数  c:运算结果
int la, lb, lc;         // 三个数组的有效长度
string x, y;            // 存储输入的超大数

1.3 通用输出逻辑

结果数组逆序存放,输出时从最后一位(最高位)向前遍历输出代码 🧑💻

// 逆序输出最终结果
for(int i = lc - 1; i >= 0; i--) cout << c[i];


2 ➕

💡 模拟小学竖式加法,逐位相加 + 处理进位,结果长度为最大数长度或 + 1。

2.1 核心逻辑

  1. 遍历每一位,将 a[i] 和 b[i] 相加存入 c[i]
  2. 处理进位:c[i]/10 加到下一位,c[i] 保留个位(%10)
  3. 最后判断最高位是否进位,有则长度 + 1

专业 📚高精度加法时间复杂度为 O(n)(n 为数字位数),属于线性高效运算。

2.2 加法函数实现 🧑💻

// 高精度加法函数
void add(int a[], int b[], int c[], int length) {
    for (int i = 0; i < length; i++) {
        c[i] += a[i] + b[i];       // 逐位相加
        c[i + 1] += c[i] / 10;     // 处理进位
        c[i] %= 10;                // 保留当前位的个位数字
    }
}

✨ 优化建议:原代码进位逻辑简化,直接用 c[i]/10 适配多进位场景,通用性更强


3 ➖

💡 模拟竖式减法,先判断大小保证被减数≥减数,逐位相减 + 处理借位,必须处理前导 0。

3.1 核心逻辑

  1. 大小判断:若减数 > 被减数,输出负号并交换两数,保证大数减小数
  2. 逐位相减,若结果 < 0,向前借 1(前一位 - 1,当前位 + 10)
  3. 处理前导 0:避免输出 0001 这类错误格式,结果为 0 时保留 1 个 0

高精度减法是唯一需要提前比较数大小的运算;前导 0 处理是输出规范的必要步骤。

⚠️ 适用场景 & 核心注意

  • 适用场景:两个超大正整数相减
  • 避坑 1:交换数字后再计算长度,否则长度错误
  • 避坑 2:前导 0 循环条件用 lc>1,保留最后一个 0,避免无输出

3.2 减法函数实现 🧑💻

// 高精度减法函数
void sub(int a[], int b[], int c[]) {
    for (int i = 0; i < lc; i++) {
        c[i] += a[i] - b[i];       // 逐位相减
        if (c[i] < 0) {            // 不够减,需要向前借位
            c[i + 1]--;
            c[i] += 10;
        }
    }
}


4 ✖️

💡 模拟竖式乘法,双层循环逐位相乘(结果存在第 i+j 位),统一处理进位,结果长度为两数长度之和。

4.1 核心逻辑

  1. 双层循环:a 的第 i 位 × b 的第 j 位,结果存入 c[i+j]
  2. 所有位相乘完成后,统一处理进位(从低位到高位)
  3. 处理前导 0,最后逆序输出

高精度乘法时间复杂度 O(n×m)(n/m 为两个数的位数);

4.2 乘法函数实现 🧑💻

// 高精度乘法函数
void mul(int a[], int b[], int c[]) {
    // 双层循环:逐位相乘
    for (int i = 0; i < la; i++) {
        for (int j = 0; j < lb; j++) {
            c[i + j] += a[i] * b[j];
        }
    }
    // 统一处理所有位的进位
    for (int i = 0; i < lc; i++) {
        c[i + 1] += c[i] / 10;
        c[i] %= 10;
    }
    // 处理前导0
    while (lc > 1 && c[lc - 1] == 0) lc--;
}


5 ➗

💡 仅实现高精度 ÷ 低精度,模拟竖式除法从最高位开始计算(和其他三个不同),余数迭代参与运算,处理前导 0。

5.1 核心逻辑

  1. 仅被除数是高精度数(存 string),除数是低精度数(int)
  2. 计算顺序:从最高位到最低位(与加减乘完全相反)
  3. 核心公式:余数×10 + 当前位 = 新被除数
  4. 商 = 新被除数 ÷ 除数,余数 = 新的被除数 % 除数
  5. 处理前导 0,逆序输出

    ⚠️ 适用场景 & 核心注意

    • 高精度 ÷ 高精度实现极复杂,入门 / 竞赛优先掌握高精度 ÷ 低精度;
    • 除法是高精度运算中唯一从高位计算的类型。

    5.2 除法函数实现 🧑💻

    long long t = 0; // 余数(开大类型,防止溢出)
    // 高精度 ÷ 低精度 函数
    void div(int a[], int b, int c[]) {
        for (int i = la - 1; i >= 0; i--) {
            t = t * 10 + a[i];    // 迭代计算当前被除数
            c[i] = t / b;         // 计算当前位的商
            t %= b;               // 更新余数,用于下一位计算
        }
        // 处理前导0
        while (lc > 1 && c[lc - 1] == 0) lc--;
    }
    


    完整可运行代码合集

    1. 高精度加法 完整代码

    #define _CRT_SECURE_NO_WARNINGS 1
    #include<iostream>
    #include<cmath>
    #include<string>
    using namespace std;
    string x, y;
    const int N = 510;
    int a[N], b[N], c[N];
    
    void add(int a[], int  b[], int  c[],int  length)
    {
    	for (int i = 0; i < length; i++)
    	{
    		c[i] += (a[i] + b[i]);
    		if (c[i] >= 10)
    		{
    			c[i] %= 10;
    			c[i + 1] = 1;
    		}
    	}
    }
    
    int main()
    {
    	cin >> x >> y;
    	int length = max(x.size(), y.size());//真实的长度,最大下标+1
    
    	for (int i = 0; i < x.size(); i++)
    		a[x.size() - 1 - i] = x[i] - '0';
    
    	for (int i = 0; i < y.size(); i++)
    		b[y.size() - 1 - i] = y[i] - '0';
    
    
    	 add(a, b, c,length);
    
    	 if (c[length] )
    		 length++;
    
    	 for (int i = length - 1; i >= 0; i--)
    	 {
    		 cout << c[i];
    	 }
    
    	return 0;
    }

    2. 高精度减法 完整代码

    
    #include<iostream>
    #include<cmath>
    #include<string>
    #include<algorithm>
    using namespace std;
    string x, y, sw;
    const int N = 1000010;
    int a[N], b[N], c[N];
    int la, lb, lc;
    //
    //
    //void sub(int a[], int b[], int c[])
    //{
    //	for (int i = 0; i < lc; i++)
    //	{
    //		if (a[i] < b[i])
    //		{
    //			a[i] += 10;
    //			a[i + 1]--;
    //		}
    //		c[i] = (a[i] - b[i]);
    //	}
    //}
    
    void sub(int a[], int b[], int c[])
    {
    	for (int i = 0; i < lc; i++)
    	{
    		c[i] += (a[i] - b[i]);
    
    		if (c[i] < 0)
    		{
    			c[i + 1]--;
    			c[i] += 10;
    		}
    	}
    }
    
    
    int main()
    {
    	cin >> x >> y;
    
    	if (x == y)
    	{
    		cout << 0 << endl;//都是0的情况
    		return 0;
    	}
    
    	//la = x.size();
    	//lb = y.size();
    	//lc = max(la, lb);
    
    	if (y.size() > x.size() || y > x)
    	{
    		cout << "-";
    
    		sw = x;
    		x = y;
    		y = sw;
    	}
    
    
    
    	la = x.size();
    	lb = y.size();
    	lc = max(la, lb);
    
    
    	for (int i = 0; i < la; i++)
    		a[la - 1 - i] = x[i] - '0';
    	for (int i = 0; i < lb; i++)
    		b[lb - 1 - i] = y[i] - '0';
    
    	sub(a, b, c);
    
    	//if (c[lc - 1] == 0)
    	//	lc--;
    
    
    	//int flag = 0;//标记最后一个不是0的下标
    	//for (int i = lc - 1; i >= 0; i++)
    	//{
    	//	if (c[i] != 0)
    	//	{
    	//		flag = i;
    	//		break;
    	//	}
    	//}
    	while (c[lc - 1]==0&&lc>=1)
    		lc--;
    
    	for (int i = lc - 1; i >= 0; i--)
    	{
    		cout << c[i];
    	}
    
    
    	return 0;
    }

    3. 高精度乘法 完整代码

    
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    const int N = 4000010;
    int la, lb, lc, a[N], b[N], c[N];
    string x,y;
    
    void mul(int a[], int b[], int c[])
    {
    	for (int i = 0; i < la; i++)
    	{
    		for (int j = 0; j < lb; j++)
    		{
    			c[i + j] += a[i] * b[j];
    		}
    	}
    
    	for (int i = 0; i < lc; i++)
    	{
    		c[i + 1] += c[i] / 10;
    		c[i] %= 10;
    	}
    
    	while (lc >  1 && c[lc - 1] == 0)
    		lc--;
    }
    int main()
    {
    	cin >> x >> y;
    	for (int i = 0; i < x.size(); i++)
    		a[i] = x[x.size() - 1 - i]  -'0';
    	for (int i = 0; i < y.size(); i++)
    		b[i] = y[y.size() - 1 - i] - '0';
    
    	la = x.size();
    	lb = y.size();
    	lc = la + lb;
    
    	mul(a, b, c);
    
    	for (int i = lc-1; i  >=0;i--)
    		cout << c[i];
    
    	return 0;
    }

    4. 高精度除法 (高精度 ÷ 低精度) 完整代码

    
    #include<iostream>
    #include<string>
    
    using namespace std;
    int a[100010], c[100010], b;
    int la, lc;
    string x ;
    long long t = 0;
    void div(int a[], int b, int c[])
    {
    	for (int i = la-1 ; i >=0 ; i--)//除法是从被除数最大为到最小位, 数组a 从后往前
    	{
    		t = t * 10 + a[i];//上一次的余数乘10再加上 a这一位上的数,就是这次的被除数
    		c[i] = t / b;//得到这一位上的答案
    		t %= b;//得到下一次的余数
    	}
    
    	while (lc> 1 && c[lc - 1] == 0)//
    		lc--;
    
    }
    int main()
    {
    	cin >> x >> b;//将 被除数数放到string ,除数就是int
    
    	la = x.size();
    	lc = la;//先将结果的位数取最大的可能值
    
    	for (int i = 0; i < la; i++)
    		a[i] = x[la - i - 1] - '0';//存被除数的每一位
    
    
    	div(a, b, c);
    
    
    	for (int i = lc - 1; i >= 0; i--)
    	{
    		cout << c[i];
    	}
    
    	return 0;
    }


    总结

    1. 核心口诀:字符串存数 → 逆序转数组 → 模拟竖式计算 → 逆序输出
    2. 核心区别:加减乘从低位计算,除法从高位计算;减法需判大小,乘法长度为两数长度和
    3. 通用避坑:必须处理进位 / 借位、前导 0,数组开足够大

    Logo

    北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

    更多推荐