高精度加法,为什么结果中只有一位数不对呢?


#include<iostream>
#include<cstdio>
#include <iomanip>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
    int a[100];
    int b[100];
    int c[100];
    //输入字符数字,用数组存转化后的数字
    //从数组后面开始相加,大于10进1,存个位的数
    string A, B;
    cin >> A >> B;
    for (int i = 0; i < A.length(); i++)
        a[i] = A[i] - 48;
    for (int i = 0; i < B.length(); i++)
        b[i] = B[i] - 48;
    int flag = 0;//标记相加是否大于10,是否需要进位
    for (int j = A.length(); j >= 0; j--)
    {
        
        if (flag == 1)
        {
            c[j] = a[j] + b[j] + 1;
            if (c[j]  >= 10)
            {
                if (j == 0)
                {
                    break;
                }
                c[j] = c[j] % 10;
                
            }
            else
            {
                if (j == 0)
                {
                    break;
                }
                flag = 0;
            }
        }
        if (flag == 0) {
            if (a[j] + b[j] >= 10)
            {
                if (j == 0)
                {
                    c[j] = (a[j] + b[j]);
                    break;
                }
                c[j] = (a[j] + b[j]) % 10;
                flag = 1;
            }
            else
            {
                c[j] = a[j] + b[j];
                if (j == 0)
                {
                    break;
                }
            }
        }
        
    }
    for (int k = 0; k < A.length(); k++)//输出
        cout << c[k];
    cout << endl;
    return 0;
}
    
    

img

正确答案应该是93000044853158582685

高精度加法,为什么结果只有一位数不对
匿名用户
C语言高精度加法 位数少的还行 位数一大就出错,求解释,谢谢10
有奖励写回答共2个回答
匿名用户
2011-03-14
首先说什么情况下会出错:
结果错误不是因为位数大,而是因为位数差大于1,你可以试下a输111,b输2,结果也会错,并且每次计算结果第一位都不一样。
分析原因:
a=1 2 3 \0 x x x …;
b=1 \0 x x …;
注意,x可能为任何字符,因为在声明一个数组时不会初始化值,
所以在运行exchange()后得到:
a=3 2 1\0 x x x
b=1 \0 x x x
故c= 4 2 x \0 x x
再运行exchange()得到c= x 2 4 \0 x x 故输出结果第一位是不可预料的
故而应将条件i<plen||i<qlen改为i<plen&&i<qlen,多出来的几位直接赋值(注意考虑进位影响哦)

这是我之前写的一个任意精度整数加法和乘法,你可以参考一下。

#include <iostream>
#include <string>
#include <iterator>

class BigInt
{
public:
    BigInt(unsigned int n = 0)
    {
        if (n == 0)
            _data.push_back('0');
        else
        {
            while (n)
            {
                _data.push_back(n % 10 + '0');
                n /= 10;
            }
        }
    }

    BigInt(const std::string &s) : _data(s.rbegin(), s.rend()) {}

    BigInt &operator+=(const BigInt &other);
    BigInt &operator*=(const BigInt &other);

    BigInt operator+(const BigInt &other) const
    {
        BigInt t = *this;
        t += other;
        return t;
    }

    BigInt operator*(const BigInt &other) const
    {
        BigInt t = *this;
        t *= other;
        return t;
    }

private:
    std::string _data;

    friend std::istream &operator>>(std::istream &is, BigInt &a);
    friend std::ostream &operator<<(std::ostream &os, const BigInt &a);
};

BigInt &BigInt::operator+=(const BigInt &other)
{
    int carry = 0;
    std::string::iterator itr1 = _data.begin();
    std::string::const_iterator itr2 = other._data.begin();
    while (itr1 != _data.end() && itr2 != other._data.end())
    {
        int a = *itr1 - '0';
        int b = *itr2 - '0';
        int c = a + b + carry;
        carry = c / 10;
        c %= 10;
        *itr1 = c + '0';
        ++itr1;
        ++itr2;
    }
    while (itr1 != _data.end())
    {
        int a = *itr1 - '0' + carry;
        carry = a / 10;
        a %= 10;
        *itr1 = a + '0';
        ++itr1;
    }
    while (itr2 != other._data.end())
    {
        int a = *itr2 - '0' + carry;
        carry = a / 10;
        a %= 10;
        _data.push_back(a + '0');
        ++itr2;
    }
    if (carry > 0)
        _data.push_back(carry + '0');
    return *this;
}

BigInt &BigInt::operator*=(const BigInt &other)
{
    BigInt r;
    for (std::size_t i = 0; i < other._data.size(); i++)
    {
        int x = other._data[i] - '0';
        int carry = 0;
        BigInt t = *this;
        for (std::string::iterator itr = t._data.begin(); itr != t._data.end(); ++itr)
        {
            int y = *itr - '0';
            int a = x * y + carry;
            *itr = a % 10 + '0';
            carry = a / 10;
        }
        if (carry > 0)
            t._data.push_back(carry + '0');
        if (i > 0)
        {
            std::string zeros(i, '0');
            t._data.insert(t._data.begin(), zeros.begin(), zeros.end());
        }
        r += t;
    }
    *this = r;
    return *this;
}

std::istream &operator>>(std::istream &is, BigInt &a)
{
    std::string s;
    is >> s;
    a = s;
    return is;
}

std::ostream &operator<<(std::ostream &os, const BigInt &a)
{
    std::copy(a._data.rbegin(), a._data.rend(), std::ostream_iterator<char>(os));
    return os;
}

int main()
{
    BigInt a, b;
    std::cin >> a >> b;
    std::cout << "a + b = " << a + b << std::endl;
    std::cout << "a * b = " << a * b << std::endl;
    return 0;
}