高精度加法

高精度运算在C++中通常是通过字符串或数组来实现的,因为标准库中的整型变量通常不能存储超过32位或64位的数值。以下是一个高精度加法的示例代码:

#include<bits/stdc++.h>
using namespace std; 
//高精度加法 
string highAccAdd(const string &a, const string &b) {
    string result;
    int carry = 0;
    // 反转字符串,便于从个位开始逐位相加
    string A = a, B = b;
    reverse(A.begin(), A.end());
    reverse(B.begin(), B.end());
    
    for (size_t i = 0; i < A.length() || i < B.length(); ++i) {
        int x = i < A.length() ? A[i] - '0' : 0;
        int y = i < B.length() ? B[i] - '0' : 0;
        int sum = x + y + carry;
        result += (sum % 10) + '0'; // 更新结果字符串
        carry = sum / 10; // 更新进位
    }
    
    if (carry > 0) {
        result += '1'; // 如果最后还有进位,添加到结果字符串末尾
    }
    
    reverse(result.begin(), result.end()); // 最终结果需要反转回来
    return result;
}
 
int main() {
    string num1 = "123456789";
    string num2 = "987654321";
    string sum = highAccAdd(num1, num2);
    cout << sum << endl;
    return 0;
}
#include<iostream>
#include<vector>//使用vector容器前需包含此文件 
using namespace std;
//vector(vector &v) ; //加上'&' 为引用数组v,则不需要再拷贝一份,提高效率
vector<int> add(vector<int> &A,vector<int> &B)
{ 
    vector<int> C;
    //进位标识符t
    int t=0;
    for(int i=0;i<B.size()||i<A.size();i++)
    {
        /*
        两个if语句都是在判断A或B容器对应的数位上是否还有数据
        如果没有则对应数位上是+0,即不加。
        */
        if(i<A.size()) t+=A[i];
        if(i<B.size()) t+=B[i];
        //要的是t个位上的数
        C.push_back(t%10);
        //舍弃掉个位数,让t十位数上的值参与到下一位数的运算中
        t/=10;
    }
    //如果t不等于零,则在最高位补1。对应数位相加(两位数的加法),进位是0或1;
    if(t) C.push_back(1);
    return C;
}
int main()
{
    string a,b;
    /*
    vector<int> 把vector理解成一个数组,但与数组不同的是:
    vector是动态储存,保存在堆中。
    动态扩展是找到比原来更大的内存空间,将原数据拷贝到新空间,释放 原 空间
    */
    vector<int> A,B; 
    cin >> a >> b; 
    /*
    push_back()是将括号里的元素插入至尾部
    A.push_back(a[i]-'0')//意味着将a[i]-'0'这个数插到A容器的最后面
    但由于A容器中无元素,所以插到了第一位上
    */
	//逆序读入,方便于运算
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0'); 
    vector<int> C=add(A,B);
	//逆序输出
    for(int i=C.size()-1;i>=0;i--) cout << C[i];
    return 0; 
}

这段代码实现了高精度加法,其中highAccAdd函数接受两个字符串参数,代表要相加的高精度数值,并返回它们的和。在实现中,我们通过字符串反转对字符进行逐位处理,避免了直接将字符转换为数值的需要,这样可以有效处理任意长度的数值。最后,结果字符串需要再次反转并返回。

高精度减法

在C++中实现高精度减法稍微复杂一些,因为需要处理借位和负数的情况。下面是一个高精度减法的示例代码:

#include <bits/stdc++.h> 
using namespace std; 
//高精度减法  
string highAccSubtract(const string &a, const string &b) {
    string result;
    int borrow = 0;
    // 假设 a >= b
    // 反转字符串,便于从个位开始逐位相减
    string A = a, B = b;
    if (a < b) {
        string tmp = A;
        A = b;
        B = tmp;
        borrow = 1; // 标记结果为负数
    } 
    reverse(A.begin(), A.end());
    reverse(B.begin(), B.end());
    
    for (size_t i = 0; i < A.length(); ++i) {
        int x = A[i] - '0';
        int y = (i < B.length()) ? B[i] - '0' : 0;
        int diff = x - y - borrow;
        
        if (diff < 0) {
            diff += 10; // 借位
            borrow = 1;
        } else {
            borrow = 0;
        }
        result += diff + '0'; // 更新结果字符串
    }
    // 移除结果字符串前导的0
    while (result.length() > 1 && result.back() == '0') {
        result.pop_back();
    }
    if (borrow) {
        // 如果最后还有借位,说明原始的a < b,返回负数结果
        result = "-" + result;
    }
    reverse(result.begin(), result.end()); // 最终结果需要反转回来
    return result;
}

int main() {
    string num1 = "123456789";
    string num2 = "98765432";
    string diff = highAccSubtract(num1, num2);
    cout << diff << endl;
    
    // 负数示例
    num1 = "123456789";
    num2 = "1234567891";
    diff = highAccSubtract(num1, num2);
    cout << diff << endl;
    
    return 0;
}
#include<bits/stdc++.h>
#include<vector>
 
using namespace std;
/*
判断a与b的大小
*/
bool check(vector<int> &a,vector<int> &b)
{
    //长度不相等,直接返回a.size()>b.size(),如果a.size()>b.size()则为真,否则为假
    if(a.size()!=b.size()) return a.size()>b.size();
    //长度不相等
    for(int i=a.size();i>=0;i--)//从最高位开始判断
    //如果最高位不相等
      if(a[i]!=b[i])
    //同上
        return a[i]>b[i];
    //两种情况都判断过还是没结果,说明a=b,直接返回真
    return true;
}
//减,对应数位相减
vector<int> sub(vector<int> &a,vector<int> &b)
{
    //经过check函数之后,a的大小一定大于b
    vector<int> C;//定义容器C
    int t=0;
    for(int i=0;i<a.size();i++)
    {
        t+=a[i];
        if(i<b.size()) t-=b[i];
        //倘若相减为负数,那么需进行借位操作。为正也不影响
        C.push_back((t+10)%10);
        //重新对t赋值
        if(t<0) t=-1;
        else t=0;
    }
    //这一步是去前导0,如果用数组来做,那就是压缩数组C的体积
    //注意即使全为0,那么就要保存最后一位
    while(C.size()>1&&C.back()==0) C.pop_back();//去顶
    return C;
}
int main()
{
    string a,b;
    cin >> a >> b;
    vector<int> A,B,C;
    
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');
 
    
    if(check(A,B))
    {
        C=sub(A,B);
        for(int i=C.size()-1;i>=0;i--) cout << C[i];
        return 0;
    }
    else
    {
        C=sub(B,A);
        //如果A的长度小于B,提前输出一个符号
        cout << "-";
        for(int i=C.size()-1;i>=0;i--) cout << C[i];
        return 0;
    }
    
}

在这段代码中,highAccSubtract函数首先判断a是否小于b,如果是,则交换它们并标记结果为负数。然后,它逐位相减,处理借位,并构建结果字符串。最后,如果最初a小于b,则在结果前添加负号。同样地,我们需要移除结果字符串前导的0,并在返回结果之前将字符串反转回来。

请注意,这段代码没有处理字符串转换为数值时的溢出问题。在实际应用中,你可能需要添加额外的逻辑来处理非常大的数值,这些数值的每一位相减都可能导致溢出。此外,这个实现假定输入的字符串都是有效的正整数表示,并且没有前导零。在实际应用中,你可能需要添加额外的输入验证来确保这些假设成立。