• C++
  • C++ 高精度的四则运算方法

  • @ 2025-5-13 20:41:01

C++ 高精度四则运算教程(通俗易懂,0基础适用)

http://139.224.60.150/discuss/681322e35309f0329ceeeb2e#1746085445133

在C++中,基本的数据类型如 intlong long 等都有其数值范围的限制。当我们需要处理非常大的整数时,这些数据类型就无能为力了。这时就需要使用高精度算法(也叫大数运算)来模拟手算过程,完成加减乘除等操作。

本教程将从零开始,带你一步步实现高精度的四则运算:加法、减法、乘法和除法


✅ 前置知识

  • 了解C++基本语法
  • 会使用 vectorstring
  • 了解函数的基本定义与调用
  • 使用命名空间:using namespace std;

🧠 思路说明

我们使用字符串或数组来保存每一位数字,然后像小学列竖式那样进行逐位计算,并处理进位或借位问题。


📦 准备工作:引入头文件 & 命名空间

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

🔢 数据结构设计

我们将每个大整数存储为一个字符型的向量(vector<int>),其中个位在前,高位在后,便于从低位开始计算。

例如:123456 存储为 {6,5,4,3,2,1}


➕ 高精度加法

💡 原理:列竖式加法 + 进位处理

vector<int> add(const vector<int>& A, const vector<int>& B) {
    vector<int> C;
    int t = 0; // 进位
    for (int i = 0; i < A.size() || i < B.size() || t; ++i) {
        if (i < A.size()) t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    return C;
}

🧪 示例:

vector<int> A = {1, 2}; // 21
vector<int> B = {9, 8}; // 89
vector<int> C = add(A, B); // 输出应为 110 -> {0,1,1}

➖ 高精度减法

❗ 注意:必须保证 A >= B,否则要处理负号

// 判断A是否大于等于B
bool cmp(const vector<int>& A, const vector<int>& B) {
    if (A.size() != B.size()) return A.size() > B.size();
    for (int i = A.size()-1; i >=0; --i)
        if (A[i] != B[i]) return A[i] > B[i];
    return true;
}

vector<int> sub(vector<int> A, vector<int> B) {
    vector<int> C;
    int t = 0; // 借位
    for (int i = 0; i < A.size(); ++i) {
        t = A[i] - t;
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        t = t < 0 ? 1 : 0;
    }

    // 去掉前导0
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

🧪 示例:

vector<int> A = {3, 2, 1}; // 123
vector<int> B = {1};       // 1
vector<int> C = sub(A, B); // 应输出 122 -> {2,2,1}

✖️ 高精度乘法(单精度)

💡 原理:模拟手算,一位一位相乘并累加

vector<int> mul(const vector<int>& A, int b) {
    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size() || t; ++i) {
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }
    return C;
}

🧪 示例:

vector<int> A = {3, 2, 1}; // 123
vector<int> C = mul(A, 2); // 246 -> {6,4,2}

➗ 高精度除法(单精度)

💡 原理:从高位到低位依次做除法,记录商和余数

vector<int> div(const vector<int>& A, int b, int& r) {
    vector<int> C;
    r = 0;
    for (int i = A.size() - 1; i >= 0; --i) {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    reverse(C.begin(), C.end());
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

🧪 示例:

vector<int> A = {6, 4, 2}; // 246
int r;
vector<int> C = div(A, 2, r); // 商为123,余数为0

🔄 输入输出转换函数

为了方便输入输出,我们需要两个辅助函数:

字符串转高精度向量

vector<int> strToVec(string s) {
    vector<int> res;
    for (int i = s.size()-1; i >=0; --i)
        res.push_back(s[i] - '0');
    return res;
}

高精度向量转字符串

string vecToStr(vector<int>& v) {
    string res;
    for (int i = v.size()-1; i >=0; --i)
        res += to_string(v[i]);
    return res;
}

🧩 完整示例程序:加法演示

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

vector<int> add(const vector<int>& A, const vector<int>& B) {
    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size() || i < B.size() || t; ++i) {
        if (i < A.size()) t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    return C;
}

vector<int> strToVec(string s) {
    vector<int> res;
    for (int i = s.size()-1; i >=0; --i)
        res.push_back(s[i] - '0');
    return res;
}

string vecToStr(vector<int>& v) {
    string res;
    for (int i = v.size()-1; i >=0; --i)
        res += to_string(v[i]);
    return res;
}

int main() {
    string a, b;
    cout << "请输入两个大整数:" << endl;
    cin >> a >> b;

    vector<int> A = strToVec(a);
    vector<int> B = strToVec(b);

    vector<int> sum = add(A, B);
    cout << "它们的和是:" << vecToStr(sum) << endl;

    return 0;
}

🧮 拓展练习

类型 题目 难度
加法 大数相加
减法 大数相减 ⭐⭐
乘法 大数 × 小数
大数 × 大数 ⭐⭐⭐
除法 大数 ÷ 小数 ⭐⭐
大数 ÷ 大数 ⭐⭐⭐⭐

📌 小结

操作 函数名 说明
加法 add() 支持任意两数相加
减法 sub() 要求 A ≥ B
乘法 mul() 和小整数相乘
除法 div() 和小整数相除,返回商和余数

🧠 技巧总结

  • 倒序存储:个位在前,高位在后,方便对齐计算。
  • 去前导0:结果中去掉多余的前导0。
  • 比较大小:用于判断减法顺序。
  • 封装函数:把每个操作写成函数,方便复用。

如果你已经掌握了上面的内容,恭喜你已经具备了编写任意精度计算器的能力!

🎉 你可以尝试实现一个完整的高精度计算器程序!


📌 提示:可以结合 switch 实现菜单选择不同的运算类型。


如有任何问题,欢迎继续提问!

13 条评论

  • @ 2025-5-19 20:47:49
    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    // 大数除以小数的除法函数
    // A为存储大数的数组(逆序存储,个位在索引0),b为小整数,r用于返回余数
    vector<int> div(const vector<int>& A, int b, int& r) {
        vector<int> C;  // 存储商的数组
        r = 0;          // 初始化余数为0
    
        // 从高位到低位遍历大数A的每一位
        for (int i = A.size() - 1; i >= 0; --i) {
            // 将上一步的余数乘以10再加上当前位数字,得到新的被除数
            r = r * 10 + A[i]; 
            // 计算当前位的商并添加到结果数组C中
            C.push_back(r / b); 
            // 更新余数
            r %= b; 
        }
    
        // 由于是从高位开始计算,结果数组C是逆序的,将其反转
        reverse(C.begin(), C.end()); 
        // 移除前导零(如果有)
        while (C.size() > 1 && C.back() == 0) C.pop_back(); 
    
        return C;
    }
    
    // 将字符串表示的大数转换为逆序存储的数组
    // 例如 "123" 转换为 [3, 2, 1]
    vector<int> strToVec(string s) {
        vector<int> res;
        for (int i = s.size() - 1; i >= 0; --i)
            res.push_back(s[i] - '0');  // 将字符转换为数字并添加到数组
        return res;
    }
    
    // 将逆序存储的数组转换为字符串表示的大数
    // 例如 [3, 2, 1] 转换为 "123"
    string vecToStr(vector<int>& v) {
        string res;
        for (int i = v.size() - 1; i >= 0; --i)
            res += to_string(v[i]);  // 将数字转换为字符并拼接成字符串
        return res;
    }
    
    int main() {
        string a;
        cout << "请输入一个大整数:" << endl;
        cin >> a;  // 输入大数
    
        int b, r;
        cout << "请输入一个小整数:" << endl;
        cin >> b;  // 输入小数
    
        // 将字符串形式的大数转换为逆序存储的数组
        vector<int> A = strToVec(a); 
    
        // 执行除法运算,同时得到商和余数
        vector<int> sum = div(A, b, r); 
    
        // 输出商
        cout << "它们的商是:" << endl << vecToStr(sum) << endl; 
        // 输出余数
        cout << "余数是:" << r << endl; 
    
        return 0;
    }
    

    代码功能说明

    这段C++ 代码实现了大整数(用字符串表示)除以小整数的功能,具体包括:

    1. div 函数:实现大整数除以小整数的核心逻辑,通过模拟除法运算过程,从高位到低位逐位计算商和余数,最后对结果数组进行反转和去除前导零操作。
    2. strToVec 函数:将输入的字符串形式的大整数转换为逆序存储的整数数组,方便后续计算。
    3. vecToStr 函数:将表示大整数的逆序数组转换回字符串形式,便于输出结果展示。
    4. main 函数:负责与用户交互,获取输入的大整数和小整数,调用上述函数完成除法运算并输出商和余数。
    • @ 2025-5-19 20:46:54
      #include <iostream>
      #include <vector>
      #include <string>
      #include <algorithm>
      using namespace std;
      
      vector<int> div(const vector<int>& A, int b, int& r) {
      	vector<int> C;
      	r = 0;
      	for (int i = A.size() - 1; i >= 0; --i) {
      		r = r * 10 + A[i];
      		C.push_back(r / b);
      		r %= b;
      	}
      	reverse(C.begin(), C.end());
      	while (C.size() > 1 && C.back() == 0) C.pop_back();
      	return C;
      }
      
      vector<int> strToVec(string s) {
      	vector<int> res;
      	for (int i = s.size()-1; i >=0; --i)
      		res.push_back(s[i] - '0');
      	return res;
      }
      string vecToStr(vector<int>& v) {
      	string res;
      	for (int i = v.size()-1; i >=0; --i)
      		res += to_string(v[i]);
      	return res;
      }
      int main() {
      	string a;
      	cout << "请输入一个大整数:" << endl;
      	cin >> a;
      	int b,r;
      	cout << "请输入一个小整数:" << endl;
      	cin>>b;
      	
      	vector<int> A = strToVec(a);
      	
      	vector<int> sum = div(A, b,r);
      	cout << "它们的积是:" <<endl<< vecToStr(sum) << endl<<r<<endl;
      	return 0;
      }
      
      
      • @ 2025-5-19 20:26:55
        #include <iostream>
        #include <vector>
        #include <string>
        #include <algorithm>
        using namespace std;
        
        // 大数乘以小数的乘法函数
        // A为存储大数的数组(逆序存储,个位在索引0),b为小整数
        vector<int> mul(const vector<int>& A, int b) {
            vector<int> C;  // 存储结果的数组
            int t = 0;      // 进位值
            
            // 遍历A的每一位并处理进位,直到所有位处理完毕且进位为0
            for (int i = 0; i < A.size() || t; ++i) {
                if (i < A.size()) t += A[i] * b;  // 累加当前位乘积和进位
                C.push_back(t % 10);             // 存储当前位结果(取模10)
                t /= 10;                         // 更新进位(整除10)
            }
            
            // 移除前导零(如果有)
            while (C.size() > 1 && C.back() == 0) C.pop_back();
            
            return C;
        }
        
        // 将字符串表示的大数转换为逆序存储的数组
        // 例如 "123" 转换为 [3, 2, 1]
        vector<int> strToVec(string s) {
            vector<int> res;
            for (int i = s.size() - 1; i >= 0; --i)
                res.push_back(s[i] - '0');  // 字符转数字
            return res;
        }
        
        // 将逆序存储的数组转换为字符串表示的大数
        // 例如 [3, 2, 1] 转换为 "123"
        string vecToStr(vector<int>& v) {
            string res;
            for (int i = v.size() - 1; i >= 0; --i)
                res += to_string(v[i]);  // 数字转字符并拼接
            return res;
        }
        
        int main() {
            string a;
            cout << "请输入一个大整数:" << endl;
            cin >> a;  // 输入大数
            
            int b;
            cout << "请输入一个小整数:" << endl;
            cin >> b;  // 输入小数
            
            // 将字符串转换为逆序数组
            vector<int> A = strToVec(a);
            
            // 执行乘法运算
            vector<int> sum = mul(A, b);
            
            // 输出结果
            cout << "它们的积是:" << endl << vecToStr(sum) << endl;
            
            return 0;
        }
        

        代码功能说明:

        这段C++程序实现了高精度整数(大数)与普通整数(小数)的乘法运算,主要功能包括:

        1. 大数存储:使用vector<int>逆序存储大数的每一位(个位在索引0)。
        2. 字符串转换:通过strToVecvecToStr函数实现字符串与数值数组的相互转换。
        3. 乘法运算mul函数模拟竖式乘法,逐位相乘并处理进位,确保高精度计算的正确性。
        4. 输入输出:提供友好的交互界面,支持用户输入大数和小数,并输出计算结果。

        这种实现方式能够处理远超普通数据类型范围的大整数乘法,适用于需要高精度计算的场景。

        • @ 2025-5-19 20:25:45
          #include <iostream>
          #include <vector>
          #include <string>
          #include <algorithm>
          using namespace std;
          
          vector<int> mul(const vector<int>& A, int b) {
          	vector<int> C;
          	int t = 0;
          	for (int i = 0; i < A.size() || t; ++i) {
          		if (i < A.size()) t += A[i] * b;
          		C.push_back(t % 10);
          		t /= 10;
          	}
          	return C;
          }
          vector<int> strToVec(string s) {
          	vector<int> res;
          	for (int i = s.size()-1; i >=0; --i)
          		res.push_back(s[i] - '0');
          	return res;
          }
          string vecToStr(vector<int>& v) {
          	string res;
          	for (int i = v.size()-1; i >=0; --i)
          		res += to_string(v[i]);
          	return res;
          }
          int main() {
          	string a;
          	cout << "请输入一个大整数:" << endl;
          	cin >> a;
          	int b;
          	cout << "请输入一个小整数:" << endl;
          	cin>>b;
          	
          	vector<int> A = strToVec(a);
          	
          	vector<int> sum = mul(A, b);
          	cout << "它们的积是:" <<endl<< vecToStr(sum) << endl;
          	return 0;
          }
          
          
          • @ 2025-5-15 21:27:38

            以下是添加了详细注释的代码,重点解释了高精度减法的逻辑和负数处理机制:

            #include <iostream>
            #include <string>
            #include <vector>   // 使用 vector 必须包含这个头文件
            #include <algorithm>
            using namespace std;
            
            // 高精度减法函数:计算两个大整数的差(需保证被减数 >= 减数)
            vector<int> sub(vector<int> A, vector<int> B);
            
            // 字符串比较函数:判断字符串表示的数字 A 是否大于等于 B
            bool cmp(const string& A, const string& B);
            
            // 字符串转数字向量:将字符串形式的大整数转换为低位在前的向量表示
            vector<int> strToVec(string s);
            
            // 打印数字向量:按高位到低位顺序输出向量表示的大整数
            void printVec(vector<int>& v);
            
            // 向量转字符串:将低位在前的向量表示转换为高位在前的字符串形式
            string vecToStr(vector<int>& v);
            
            bool flag = true; // 负数标记:true 表示结果为正,false 表示结果为负
            
            int main() {
                string s1, s2;
                cin >> s1 >> s2;
            
                // 确保被减数 >= 减数,否则交换并标记负数
                if (cmp(s1, s2) == false) {
                    swap(s1, s2); // 交换两个数字字符串
                    flag = false; // 标记结果为负数
                }
            
                // 转换字符串为低位在前的数字向量(例如 "123" -> {3,2,1})
                vector<int> A = strToVec(s1);
                vector<int> B = strToVec(s2);
                
                // 执行高精度减法(要求 A >= B,结果符号由 flag 控制)
                vector<int> C = sub(A, B); 
                
                // 将结果向量转换为字符串
                string res = vecToStr(C);
                
                // 输出符号(如果结果为负)
                if (flag == false) {
                    cout << "-";
                }
                
                cout << res << endl;
                return 0;
            }
            
            // 判断字符串表示的数字 A 是否大于等于 B
            bool cmp(const string& A, const string& B) {
                if (A.size() != B.size()) 
                    return A.size() > B.size(); // 长度更长的数字更大
                return A >= B; // 长度相同则按字典序比较(字符串直接比较等价于数字大小)
            }
            
            // 高精度减法核心函数(假设 A >= B)
            vector<int> sub(vector<int> A, vector<int> B) {
                vector<int> C; // 存储结果(低位在前)
                int t = 0; // 借位标记:0 表示无借位,1 表示需要借位
                
                // 遍历被减数的每一位(减数长度不足时视为 0)
                for (int i = 0; i < A.size(); ++i) {
                    // 计算当前位的实际值:被减数当前位 - 借位 - 减数当前位(若存在)
                    t = A[i] - t;
                    if (i < B.size()) t -= B[i]; // 减去减数对应位(若有)
                    
                    // 处理借位:若结果为负数,需借位并调整当前位值
                    C.push_back((t + 10) % 10); // 当前位结果(加10后取模处理负数)
                    t = t < 0 ? 1 : 0; // 更新借位标记
                }
            
                // 去除前导零(例如结果为 {0,0,1} 应转为 {1})
                while (C.size() > 1 && C.back() == 0) 
                    C.pop_back(); // 从末尾删除(向量低位在前,末尾是最高位)
                
                return C;
            }
            
            // 字符串转向量:将字符串逆序转换为数字向量(低位在前)
            vector<int> strToVec(string s) {
                vector<int> res;
                for (int i = s.size() - 1; i >= 0; i--) 
                    res.push_back(s[i] - '0'); // 字符转数字,低位先存入(例如 '3' 是个位)
                return res;
            }
            
            // 打印向量:按高位到低位顺序输出(例如 {3,2,1} 输出 "123")
            void printVec(vector<int>& v) {
                for (int i = v.size() - 1; i >= 0; i--) 
                    cout << v[i]; // 从向量末尾(最高位)开始遍历
                cout << endl;
            }
            
            // 向量转字符串:将低位在前的向量转为高位在前的字符串(例如 {0,1,1} -> "110")
            string vecToStr(vector<int>& v) {
                string res;
                for (int i = v.size() - 1; i >= 0; --i) 
                    res += to_string(v[i]); // 从最高位开始拼接数字字符
                return res;
            }
            

            关键逻辑解析

            1. 符号处理

              • 通过 cmp 函数比较两个字符串的大小,若被减数 < 减数,则交换两者并标记 flag = false,最终结果添加负号。
              • 注意:此代码仅处理非负数的减法,若输入包含负数需额外扩展(见下方扩展建议)。
            2. 高精度减法核心逻辑

              • 借位处理
                • 当前位计算:t = A[i] - t - B[i]t 为上一位的借位,初始为 0)。
                • 若结果为负数(t < 0),需向高位借位:当前位值为 (t + 10) % 10,借位标记 t = 1
              • 示例:计算 321 - 123(向量为 A={1,2,3}, B={3,2,1}):
                • 个位:3 - 0 - 1 = 2 → 结果 2,无借位。
                • 十位:2 - 0 - 2 = 0 → 结果 0,无借位。
                • 百位:1 - 0 - 3 = -2 → 结果 (-2 + 10) % 10 = 8,借位 1(但百位是最高位,借位自动消失)。
                • 最终向量为 {8,0,2},转换为字符串为 208
            3. 前导零处理

              • 减法可能产生前导零(如 100 - 99 = 1),通过 while (C.size() > 1 && C.back() == 0) 删除末尾的零(向量末尾是最高位)。

            扩展建议(处理负数输入)

            若需要支持负数减法,可添加以下逻辑:

            1. 判断输入是否包含负号,提取数值部分。
            2. 根据符号组合(正正、正负、负正、负负)调用加法或减法:
              • (-A) - (-B) = B - A
              • A - (-B) = A + B
              • (-A) - B = -(A + B)

            常见错误避免

            • 输入带负号的处理:当前代码假设输入为非负数,若输入包含 -,需在 strToVec 中先去除符号并标记符号位。
            • 向量长度差异:减法循环仅遍历被减数长度,减数不足时自动视为 0,无需补零。
            • 前导零判断C.size() > 1 确保至少保留一个零(如结果为 0 时避免空向量)。
            • @ 2025-5-15 21:27:00
              #include<iostream>
              #include <string>
              #include <vector>   // 使用 vector 必须包含这个头文件
              #include <algorithm>
              using namespace std;
              vector<int> sub(vector<int> A, vector<int> B);
              bool cmp(const string& A, const string& B);
              vector<int> strToVec(string s);
              void printVec(vector<int>& v);
              string vecToStr(vector<int>& v);
              bool flag = true;//负数的标记
              
              int main() {
              	string s1, s2;
              	cin >> s1 >> s2;
              	//必须保证 A >= B,否则要处理负号
              	if(cmp(s1,s2)==false){
              		swap(s1,s2);
              		flag = false;
              	}
              	
              	vector<int> A = strToVec(s1);
              	vector<int> B = strToVec(s2);
              	vector<int> C = sub(A, B); // 输出应为 110 -> {0,1,1}
              	string res = vecToStr(C);
              	if(flag == false){
              		cout<<"-";
              		
              	}
              	cout<<res<<endl;
              	return 0;
              }
              // 判断A是否大于等于B
              bool cmp(const string& A, const string& B) {
              	if (A.size() != B.size()) return A.size() > B.size();
              	return A >= B;
              }
              
              vector<int> sub(vector<int> A, vector<int> B) {
              	vector<int> C;
              	int t = 0; // 借位
              	for (int i = 0; i < A.size(); ++i) {
              		t = A[i] - t;
              		if (i < B.size()) t -= B[i];
              		C.push_back((t + 10) % 10);
              		t = t < 0 ? 1 : 0;
              	}
              	
              	// 去掉前导0
              	while (C.size() > 1 && C.back() == 0) C.pop_back();
              	return C;
              }
              
              
              vector<int> strToVec(string s) {
              	vector<int> res;
              	for (int i = s.size() - 1; i >= 0; i--)
              		res.push_back(s[i] - '0');
              	return res;
              }
              void printVec(vector<int>& v) {
              	for (int i = v.size() - 1; i >= 0; i--)
              		cout << v[i];
              	cout << endl;
              }
              string vecToStr(vector<int>& v) {
              	string res;
              	for (int i = v.size()-1; i >=0; --i)
              		res += to_string(v[i]);//string to_string(value);          // 数转字符串
              	return res;
              }
              
              
              • @ 2025-5-15 20:53:34

                以下是添加了详细注释的代码:

                #include <iostream>
                #include <string>
                #include <vector>   // 使用 vector 必须包含这个头文件
                #include <algorithm>
                using namespace std;
                
                // 高精度加法:计算两个大整数的和
                vector<int> add(const vector<int>& A, const vector<int>& B);
                
                // 字符串转数字向量:将字符串形式的大整数转换为低位在前的向量表示
                vector<int> strToVec(string s);
                
                // 打印数字向量:按高位到低位顺序输出向量表示的大整数
                void printVec(vector<int>& v);
                
                // 向量转字符串:将低位在前的向量表示转换为高位在前的字符串形式
                string vecToStr(vector<int>& v);
                
                int main() {
                    string s1, s2;
                    cin >> s1 >> s2;
                
                    // 转换输入字符串为数字向量,低位在前存储(例如"123"转为{3,2,1})
                    vector<int> A(strToVec(s1));
                    vector<int> B = strToVec(s2);
                    
                    // 执行高精度加法(例如{3,2,1} + {7,8,9} = {0,1,2,1} 表示 123+987=1110)
                    vector<int> C = add(A, B); // 输出应为 110 -> {0,1,1}
                    
                    // 将结果向量转换为字符串并输出
                    string res = vecToStr(C);
                    cout << res << endl;
                    
                    return 0;
                }
                
                // 高精度加法实现:逐位相加并处理进位
                vector<int> add(const vector<int>& A, const vector<int>& B) {
                    vector<int> C;
                    int t = 0; // 进位值
                    
                    // 遍历两个向量的每一位,处理到最高位以及可能的进位
                    for (int i = 0; i < A.size() || i < B.size() || t; ++i) {
                        if (i < A.size()) t += A[i]; // 累加A的当前位
                        if (i < B.size()) t += B[i]; // 累加B的当前位
                        
                        C.push_back(t % 10); // 当前位结果(取模)
                        t /= 10;             // 计算进位(整除10)
                    }
                    
                    return C; // 返回低位在前的结果向量
                }
                
                // 字符串转向量:将字符串逆序转换为数字向量(低位在前)
                vector<int> strToVec(string s) {
                    vector<int> res;
                    
                    // 从字符串末尾向前遍历(即从低位到高位)
                    for (int i = s.size() - 1; i >= 0; i--)
                        res.push_back(s[i] - '0'); // 字符转数字并添加到向量
                    
                    return res; // 返回低位在前的向量(例如"123"转为{3,2,1})
                }
                
                // 向量打印:按高位到低位顺序输出
                void printVec(vector<int>& v) {
                    // 从向量末尾向前遍历(即从高位到低位)
                    for (int i = v.size() - 1; i >= 0; i--)
                        cout << v[i];
                    
                    cout << endl;
                }
                
                // 向量转字符串:将低位在前的向量转换为高位在前的字符串
                string vecToStr(vector<int>& v) {
                    string res;
                    
                    // 从向量末尾向前遍历(即从高位到低位)
                    for (int i = v.size() - 1; i >= 0; --i)
                        res += to_string(v[i]); // 数字转字符并拼接
                    
                    return res; // 返回正确顺序的字符串(例如{0,1,1}转为"110")
                }
                

                代码关键点说明:

                1. 存储结构

                  • 数字向量采用低位在前的存储方式(例如"123"存储为{3,2,1}
                  • 这种方式便于加法时处理进位(直接在末尾追加新位)
                2. 高精度加法核心逻辑

                  for (int i = 0; i < A.size() || i < B.size() || t; ++i)
                  
                  • 循环条件覆盖两个加数的所有位以及最后的进位
                  • 逐位相加并处理进位,确保所有位都被计算
                3. 字符串与向量转换

                  • strToVec:反转字符串顺序并转换为数字向量
                  • vecToStr:反转向量顺序并转换为字符串
                  • 两次反转确保最终结果顺序正确
                4. 输入输出流程

                  输入字符串 → 转为低位在前的向量 → 加法运算 → 转为高位在前的字符串 → 输出
                  

                这种实现方式通过模拟手工加法的过程,有效处理了超出普通数据类型范围的大整数运算。

                • @ 2025-5-15 20:50:57

                  在C++中,to_string() 是一个标准库函数,其主要作用是将数值类型(如整数、浮点数)转换为对应的字符串表示形式。该函数极大地简化了数值与文本之间的转换过程,避免了传统C风格转换(如 sprintf)的复杂性。

                  核心功能

                  to_string() 可以将以下类型转换为字符串:

                  • 整数类型intlonglong long 等。
                  • 浮点类型floatdoublelong double 等。

                  函数原型

                  #include <string>  // 必须包含此头文件
                  
                  string to_string(int value);          // 整数转字符串
                  string to_string(long value);         // 长整型转字符串
                  string to_string(long long value);    // 长长整型转字符串
                  string to_string(unsigned value);     // 无符号整型转字符串
                  string to_string(unsigned long value);
                  string to_string(unsigned long long value);
                  string to_string(float value);        // 单精度浮点型转字符串
                  string to_string(double value);       // 双精度浮点型转字符串
                  string to_string(long double value);  // 长双精度浮点型转字符串
                  

                  使用示例

                  1. 整数转字符串

                  #include <iostream>
                  #include <string>
                  using namespace std;
                  
                  int main() {
                      int num = 12345;
                      string str = to_string(num);  // "12345"
                      cout << "整数转字符串: " << str << endl;
                  
                      long long largeNum = 1234567890123LL;
                      string largeStr = to_string(largeNum);  // "1234567890123"
                      cout << "长整数转字符串: " << largeStr << endl;
                  }
                  

                  2. 浮点数转字符串

                  #include <iostream>
                  #include <string>
                  using namespace std;
                  
                  int main() {
                      double pi = 3.14159;
                      string piStr = to_string(pi);  // 默认保留6位小数,结果为 "3.141590"
                      cout << "浮点数转字符串: " << piStr << endl;
                  
                      float small = 0.0001f;
                      string smallStr = to_string(small);  // "0.000100"
                      cout << "小浮点数转字符串: " << smallStr << endl;
                  }
                  

                  注意事项

                  1. 浮点精度问题

                    • to_string() 默认保留6位小数,可能导致精度丢失或多余的零。例如:
                      double value = 1.23;
                      string s = to_string(value);  // "1.230000"
                      
                    • 若需自定义精度,建议使用 stringstreamfmt 库:
                      #include <sstream>
                      
                      double value = 1.23;
                      stringstream ss;
                      ss.precision(2);  // 设置精度为2位小数
                      ss << fixed << value;
                      string s = ss.str();  // "1.23"
                      
                  2. 非数值类型无法转换

                    • to_string() 仅支持数值类型。若需转换自定义类型(如类对象),需自行重载 operator<< 或编写转换函数。
                  3. 负数处理

                    • 自动处理负号,无需额外操作:
                      int negative = -42;
                      string s = to_string(negative);  // "-42"
                      

                  与其他转换方式的对比

                  方法 适用场景 示例
                  to_string() 简单数值转字符串 string s = to_string(123);
                  stringstream 自定义格式(如精度) ss << fixed << setprecision(2) << 3.14159;
                  sprintf() C风格转换(需注意缓冲区) sprintf(buf, "%d", 123);
                  std::format() C++20+ 格式化(更强大) string s = std::format("{}", 123);

                  总结

                  to_string() 是C++中最便捷的数值转字符串工具,适用于大多数简单场景。它避免了手动处理缓冲区的麻烦,但在需要精确控制格式(如小数位数)时,建议使用 stringstreamstd::format

                  • @ 2025-5-15 20:49:45

                    在C++中,vector<int> A(strToVec(s1));vector<int> B = strToVec(s2); 这两种初始化方式在功能上是等价的,但在底层机制和语义上存在一些细微差别。

                    核心区别

                    1. 语法形式

                      • vector<int> A(strToVec(s1));直接初始化(Direct Initialization)。
                      • vector<int> B = strToVec(s2);拷贝初始化(Copy Initialization)。
                    2. 底层机制

                      • 直接初始化:直接调用 vector 的构造函数,用 strToVec(s1) 的返回值构造 A
                      • 拷贝初始化:理论上会先创建一个临时 vector 对象,再通过拷贝构造函数将临时对象复制给 B,但现代编译器通常会优化掉拷贝操作(即 RVO,Return Value Optimization),最终效果与直接初始化相同。
                    3. 语义差异

                      • 直接初始化:更强调“构造”的意图,可调用任何匹配的构造函数(包括接受多个参数的构造函数)。
                      • 拷贝初始化:更强调“赋值”的意图,要求右侧表达式的类型可隐式转换为目标类型。

                    示例对比

                    假设 strToVec 函数返回一个 vector<int>

                    vector<int> strToVec(const string& s) {
                        // 将字符串转换为 vector<int>
                        return {1, 2, 3};
                    }
                    
                    // 直接初始化
                    vector<int> A(strToVec("123"));  // 直接构造 A
                    
                    // 拷贝初始化
                    vector<int> B = strToVec("456");  // 理论上先创建临时对象,再拷贝给 B,但编译器优化后等价于直接构造
                    

                    关键细节

                    1. 隐式转换限制

                      • 拷贝初始化要求右侧表达式的类型必须能隐式转换为 vector<int>。例如:
                        vector<int> C = {1, 2, 3};  // 合法,列表初始化可隐式转换为 vector
                        vector<int> D = 42;         // 非法,int 无法隐式转换为 vector
                        
                    2. 移动语义

                      • 如果 strToVec 返回的是右值(如临时对象),拷贝初始化会触发移动构造函数,避免深拷贝:
                        vector<int> E = getVector();  // 若 getVector() 返回临时对象,触发移动构造(效率高)
                        
                    3. 性能差异

                      • 在现代编译器中,两种初始化方式的性能通常无差别,因为 RVO 会优化掉临时对象的拷贝。

                    总结

                    • 功能上:两种方式都能正确初始化 vector 对象。
                    • 推荐场景
                      • 直接初始化:更通用,适用于所有场景,尤其需要显式调用特定构造函数时。
                      • 拷贝初始化:代码更简洁,适用于简单赋值场景。

                    实际编程中,建议根据代码风格和可读性选择,但需注意拷贝初始化的隐式转换限制。

                    • @ 2025-5-15 20:40:20
                      #include <iostream>
                      #include <string>
                      #include <vector>   // 使用 vector 必须包含这个头文件
                      #include <algorithm>
                      using namespace std;
                      vector<int> add(const vector<int>& A, const vector<int>& B);
                      vector<int> strToVec(string s);
                      int main() {
                      	string s1, s2;
                      	cin >> s1 >> s2;
                      
                      	vector<int> A(strToVec(s1));
                      	vector<int> B = strToVec(s2);
                      	vector<int> C = add(A, B); // 输出应为 110 -> {0,1,1}
                      	reverse(C.begin(), C.end());
                      	for (auto i : C) {
                      		cout << i;
                      	}
                      	return 0;
                      }
                      
                      vector<int> add(const vector<int>& A, const vector<int>& B) {
                      	vector<int> C;
                      	int t = 0; // 进位
                      	for (int i = 0; i < A.size() || i < B.size() || t; ++i) {
                      		if (i < A.size()) t += A[i];
                      		if (i < B.size()) t += B[i];
                      		C.push_back(t % 10);
                      		t /= 10;
                      	}
                      	return C;
                      }
                      
                      vector<int> strToVec(string s) {
                      	vector<int> res;
                      	for (int i = s.size() - 1; i >= 0; i--)
                      		res.push_back(s[i] - '0');
                      	return res;
                      }
                      
                      
                      • @ 2025-5-15 20:28:37
                        #include <iostream>
                        #include <string>
                        #include <vector>   // 使用 vector 必须包含这个头文件
                        #include <algorithm>
                        using namespace std;
                        vector<int> add(const vector<int>& A, const vector<int>& B);
                        int main() {
                        	//string ss;
                        	//cin >> ss;
                        	//cout<<ss;
                        	vector<int> A = {1, 2}; // 21
                        	vector<int> B = {9, 8}; // 89
                        	vector<int> C = add(A, B); // 输出应为 110 -> {0,1,1}
                        	reverse(C.begin(), C.end());
                        	for (auto i : C) {
                        		cout << i;
                        	}
                        	return 0;
                        }
                        
                        vector<int> add(const vector<int>& A, const vector<int>& B) {
                        	vector<int> C;
                        	int t = 0; // 进位
                        	for (int i = 0; i < A.size() || i < B.size() || t; ++i) {
                        		if (i < A.size()) t += A[i];
                        		if (i < B.size()) t += B[i];
                        		C.push_back(t % 10);
                        		t /= 10;
                        	}
                        	return C;
                        }
                        
                        
                        • @ 2025-5-13 20:42:09

                          C++高精度四则运算教程

                          在C++中,基本数据类型(如int、long long)有数值范围限制。当需要处理极大或极小数时,就需要自己实现高精度运算。本教程将从零开始教你如何用C++实现高精度的加、减、乘、除运算。

                          1. 高精度加法

                          高精度加法的核心是模拟竖式加法,逐位相加并处理进位。

                          下面是完整实现代码:

                          #include <iostream>
                          #include <string>
                          #include <algorithm>
                          using namespace std; // 使用标准命名空间,避免重复写std::
                          
                          // 高精度加法函数
                          string add(string num1, string num2) {
                              string result;
                              int carry = 0; // 进位
                              int i = num1.size() - 1;
                              int j = num2.size() - 1;
                              
                              // 逐位相加
                              while (i >= 0 || j >= 0 || carry > 0) {
                                  int sum = carry;
                                  if (i >= 0) sum += num1[i--] - '0';
                                  if (j >= 0) sum += num2[j--] - '0';
                                  
                                  result.push_back(sum % 10 + '0'); // 当前位结果
                                  carry = sum / 10; // 计算进位
                              }
                              
                              reverse(result.begin(), result.end()); // 反转字符串得到正确结果
                              return result;
                          }
                          
                          int main() {
                              string num1, num2;
                              cout << "请输入两个大整数:" << endl;
                              cin >> num1 >> num2;
                              
                              string sum = add(num1, num2);
                              cout << "两数之和为:" << sum << endl;
                              
                              return 0;
                          }
                          

                          代码解释:

                          • 将数字作为字符串处理,避免数值溢出
                          • 从最低位开始逐位相加,处理进位
                          • 最后反转字符串得到正确结果

                          2. 高精度减法

                          高精度减法的核心是模拟竖式减法,逐位相减并处理借位。

                          #include <iostream>
                          #include <string>
                          #include <algorithm>
                          using namespace std;
                          
                          // 判断num1是否大于等于num2
                          bool isGreaterOrEqual(string num1, string num2) {
                              if (num1.size() != num2.size())
                                  return num1.size() > num2.size();
                              return num1 >= num2;
                          }
                          
                          // 高精度减法函数
                          string subtract(string num1, string num2) {
                              if (!isGreaterOrEqual(num1, num2))
                                  return "-" + subtract(num2, num1);
                              
                              string result;
                              int borrow = 0; // 借位
                              int i = num1.size() - 1;
                              int j = num2.size() - 1;
                              
                              // 逐位相减
                              while (i >= 0) {
                                  int diff = (num1[i] - '0') - borrow;
                                  if (j >= 0) diff -= (num2[j] - '0');
                                  
                                  if (diff < 0) {
                                      diff += 10;
                                      borrow = 1;
                                  } else {
                                      borrow = 0;
                                  }
                                  
                                  result.push_back(diff + '0');
                                  i--; j--;
                              }
                              
                              // 去除前导零
                              while (result.size() > 1 && result.back() == '0')
                                  result.pop_back();
                              
                              reverse(result.begin(), result.end());
                              return result;
                          }
                          
                          int main() {
                              string num1, num2;
                              cout << "请输入两个大整数:" << endl;
                              cin >> num1 >> num2;
                              
                              string diff = subtract(num1, num2);
                              cout << "两数之差为:" << diff << endl;
                              
                              return 0;
                          }
                          

                          代码解释:

                          • 先判断两数大小关系,处理负数情况
                          • 逐位相减并处理借位
                          • 最后去除结果中的前导零

                          3. 高精度乘法

                          高精度乘法模拟竖式乘法,将乘数的每一位与被乘数相乘,再累加结果。

                          #include <iostream>
                          #include <string>
                          #include <vector>
                          #include <algorithm>
                          using namespace std;
                          
                          // 高精度乘法函数
                          string multiply(string num1, string num2) {
                              if (num1 == "0" || num2 == "0") return "0";
                              
                              vector<int> result(num1.size() + num2.size(), 0);
                              
                              // 逐位相乘
                              for (int i = num1.size() - 1; i >= 0; i--) {
                                  for (int j = num2.size() - 1; j >= 0; j--) {
                                      int mul = (num1[i] - '0') * (num2[j] - '0');
                                      int sum = mul + result[i + j + 1];
                                      
                                      result[i + j + 1] = sum % 10;
                                      result[i + j] += sum / 10;
                                  }
                              }
                              
                              // 转换为字符串
                              string product;
                              for (int num : result) {
                                  if (!(product.empty() && num == 0))
                                      product.push_back(num + '0');
                              }
                              
                              return product;
                          }
                          
                          int main() {
                              string num1, num2;
                              cout << "请输入两个大整数:" << endl;
                              cin >> num1 >> num2;
                              
                              string product = multiply(num1, num2);
                              cout << "两数之积为:" << product << endl;
                              
                              return 0;
                          }
                          

                          代码解释:

                          • 使用数组存储中间结果,避免溢出
                          • 双重循环处理每一位的乘法
                          • 累加中间结果并处理进位
                          • 最后转换为字符串并去除前导零

                          4. 高精度除法(整数除法)

                          高精度除法计算两数的商,采用试商的方法逐位确定商的每一位。

                          #include <iostream>
                          #include <string>
                          #include <algorithm>
                          using namespace std;
                          
                          // 判断num1是否大于等于num2
                          bool isGreaterOrEqual(string num1, string num2) {
                              if (num1.size() != num2.size())
                                  return num1.size() > num2.size();
                              return num1 >= num2;
                          }
                          
                          // 高精度减法(辅助函数)
                          string subtract(string num1, string num2) {
                              if (!isGreaterOrEqual(num1, num2))
                                  return "0";
                              
                              string result;
                              int borrow = 0;
                              int i = num1.size() - 1;
                              int j = num2.size() - 1;
                              
                              while (i >= 0) {
                                  int diff = (num1[i] - '0') - borrow;
                                  if (j >= 0) diff -= (num2[j] - '0');
                                  
                                  if (diff < 0) {
                                      diff += 10;
                                      borrow = 1;
                                  } else {
                                      borrow = 0;
                                  }
                                  
                                  result.push_back(diff + '0');
                                  i--; j--;
                              }
                              
                              while (result.size() > 1 && result.back() == '0')
                                  result.pop_back();
                              
                              reverse(result.begin(), result.end());
                              return result;
                          }
                          
                          // 高精度除法函数(整数除法)
                          pair<string, string> divide(string dividend, string divisor) {
                              if (divisor == "0") throw invalid_argument("除数不能为零");
                              if (dividend == "0") return {"0", "0"};
                              
                              string quotient;
                              string remainder = "";
                              
                              for (char digit : dividend) {
                                  remainder += digit;
                                  
                                  // 试商
                                  int q = 0;
                                  while (isGreaterOrEqual(remainder, divisor)) {
                                      remainder = subtract(remainder, divisor);
                                      q++;
                                  }
                                  
                                  quotient.push_back(q + '0');
                              }
                              
                              // 去除商的前导零
                              while (quotient.size() > 1 && quotient[0] == '0')
                                  quotient.erase(0, 1);
                              
                              return {quotient, remainder};
                          }
                          
                          int main() {
                              string dividend, divisor;
                              cout << "请输入被除数和除数:" << endl;
                              cin >> dividend >> divisor;
                              
                              try {
                                  auto [quotient, remainder] = divide(dividend, divisor);
                                  cout << "商为:" << quotient << endl;
                                  cout << "余数为:" << remainder << endl;
                              } catch (const invalid_argument& e) {
                                  cout << "错误:" << e.what() << endl;
                              }
                              
                              return 0;
                          }
                          

                          代码解释:

                          • 使用减法辅助函数实现试商过程
                          • 逐位处理被除数,确定商的每一位
                          • 返回商和余数两个结果
                          • 包含错误处理,防止除以零

                          总结

                          通过上述代码,我们实现了高精度的加、减、乘、除四则运算。核心思路是将大数字作为字符串处理,模拟竖式计算的过程,逐位处理并处理进位/借位。

                          这些算法虽然不是最高效的,但易于理解和实现,非常适合初学者掌握高精度计算的基本原理。实际应用中,你可以根据需要对代码进行优化。

                          • 1