如何在char向量上执行BigInteger乘法?

时间:2018-04-18 22:41:17

标签: c++

我在c ++中实现BigInt并试图重载乘法运算符。我将大整数存储在char矢量中。

vector<char> storage;

这是我为实现operator *(int)

所做的
BigInt BigInt::operator*(int x)
{
int extra = 0;
int dec_mod = pow(10, this->storage.size());

for (auto & g : storage) {
    g = g * x + extra;
    int mod_g = g % dec_mod;
    extra = g / dec_mod;
    g = mod_g;
}

while (extra > 0) {
    storage.push_back(extra % dec_mod);
    extra /= dec_mod;
}

return *this;
}

operator *(bigInt)函数返回错误的答案。例如,33 * 4返回1212而不是132.这是我尝试编写重载运算符*,它接受一个bigint对象:

BigInt BigInt::operator*(BigInt bigN) {
int carry = 0;

for (int i = bigN.storage.size()-1; i >= 0; i--) {

    for (int j = this->storage.size()-1; j >= 0; j--) {

        int val = (this->storage.at(i) * bigN.storage.at(j)) + carry;
        this->storage.push_back(val % 10);
        carry = val / 10;
    }

}
return *this;
}

看起来进位中的逻辑是有缺陷的,但我不确定如何解决它。

1 个答案:

答案 0 :(得分:0)

我不确定你是怎么做到这一点的,但这里是你为什么得到结果1212而不是132的演练:

BigInt operator*(int x)// x is 4
    {
        // Let's say storage holds 33, that's
        // {3, 3} in your char vector;
        int extra = 0;
        int dec_mod = pow(10, this->storage.size()); // dec_mod may be 100


        for (auto & g : storage) 
        {
            g = g * x + extra;  // same as g = 3 * 4 + 0, g = 12
            int mod_g = g % dec_mod; // same as mod_g = 12 % 100 = 12
            extra = g / dec_mod; // same as 12 / 100 = 0
            g = mod_g;  // g = 12
        }
        // Exact same thing happens on the second iteration, your storage vector
        // ends up as {12, 12};
        // That's why your result is 1212

        while (extra > 0) {
            storage.push_back(extra % dec_mod);
            extra /= dec_mod;
        }
        return *this;
    }

我不确定你是怎么做的,但这是我的尝试,就像人们会在纸上做的那样:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct BigInt
{
    BigInt(std::string num) { for (auto &i : num) storage.push_back(i - 48); }
    BigInt(std::vector<char> numVect) : storage(numVect) {}

    vector<char> storage;

    string getAsString() 
    { string str; for (auto& i : storage) str += i + 48; return str; }
    // Add 48 to turn 0 - 9 to ascii string.

    vector<char> add(vector<char>& lhs, vector<char>& rhs)
    // Add function only needed if number is multiplied by more than one digit.
    {
        // Fill with zeros to make both vectors same length.
        int sizeDiff = (int)lhs.size() - (int)rhs.size();
        if (sizeDiff < 0)
            lhs.insert(lhs.begin(), abs(sizeDiff), 0);
        else if (sizeDiff > 0)
            rhs.insert(rhs.begin(), abs(sizeDiff), 0);

        vector<char> resultVect;
        int carry = 0;
        for (int i = lhs.size() - 1; i >= 0; --i)
        {
            int result = lhs[i] + rhs[i] + carry;
            carry = result / 10;
            result %= 10;
            resultVect.insert(resultVect.begin(), result);
        }
        if (carry != 0) resultVect.insert(resultVect.begin(), carry);

        return resultVect;
    }

    BigInt operator*(BigInt rhs)
    {
        int unitPlace = 0; // Keeps track of how many zeros to add in subsequent results
        vector<char> totalVect; // Accumulated value after each addition
        vector<char> resultVect; // Result of this particular multiplication

        for (int i = rhs.storage.size() - 1; i >= 0; --i, unitPlace++)
        {
            int carry = 0;
            for (int k = 0; k < unitPlace; ++k) resultVect.push_back(0);

            for (int j = storage.size() - 1; j >= 0; j--)
            {
                int result = rhs.storage[i] * storage[j] + carry;
                carry = result / 10;
                result %= 10;

                resultVect.insert(resultVect.begin(), result);
            }
            resultVect.insert(resultVect.begin(), carry);
            totalVect = add(totalVect, resultVect); // Add sub-result
            resultVect.clear();
        }

        // Strip leading zeros
        for (int i = 0; i < totalVect.size(); ++i) {
            if (totalVect[i] == 0) totalVect.erase(totalVect.begin() + i);
            else break;
        }

        return BigInt{ totalVect };
    }
};

int main()
{
    BigInt a{ "335467" };
    BigInt b{ "1019737" };

    BigInt c = a * b;

    std::cout << c.getAsString() << '\n';

    cin.ignore();
    return 0;
}