【问题标题】:How to implement operator*= for big integers without instantiating new vector?如何在不实例化新向量的情况下为大整数实现 operator*=?
【发布时间】:2021-03-08 18:32:37
【问题描述】:

我正在尝试在 C++ 中实现一个用于处理大整数(例如> 2^64,由它们的字符串表示形式给出)的类。

我使用2^32作为数字系统的base,也就是说,我有一个向量将数字存储为从0到2^32-1的整数(uint32_t用于这)。我想通过operator*= 实现operator* 和operator*=,在我的情况下是operator*,同时我想避免在@987654333 的实现中实例化新向量(例如result) @。在互联网上,我只能通过operator*(如this 一)找到operator*= 的实现,或者只是两个大整数的operator* 的实现,例如this 一。我该怎么做?

下面是我当前对operator*=的实现:

// BASE = 1 << 32
// num: std::vector<uint32_t> num;
bignum& operator*=(const bignum &bn) {
    std::vector<uint32_t> result(size() + bn.size() + 1, 0);

    for (size_t i = 0; i < size(); ++i) {
        uint64_t carry = 0;

        for (size_t j = 0; j < bn.size(); ++j) {
            // static_cast is used to avoid overflow
            uint64_t tmp = static_cast<uint64_t>(num[i]) * bn.num[j] + result[i + j] + carry;
            result[i + j] = tmp % BASE;
            carry = tmp / BASE;
        }

        size_t index = bn.size();
        while (carry > 0) {
           uint64_t tmp = carry + result[i + index];
           result[i + index] = tmp;
           carry = tmp / BASE;
           ++index;
        }
    }

    num = result;

    return *this;
}

我很高兴收到任何建议。祝你有美好的一天!

【问题讨论】:

  • fwiw,按照“普通”运算符实现复合运算符并不好。通常,它以相反的方式完成。如果操作无法就地完成,那么恕我直言,最好不要提供复合运算符
  • num 的元素是什么?数字?
  • 在我的情况下不是,但如果 BASE 是 10,那么 num,例如 54 将存储数字或换句话说 {4, 5}。
  • 但是在谈到operator*= 时,这并不重要,不是吗?
  • 当然重要的是你想乘什么,除非你认为答案已经很明显;)

标签: c++ operator-overloading biginteger


【解决方案1】:

你应该首先实现运算符*=,就像你已经做的那样。但是你应该优化代码,让它重用this的容器num,以避免分配新的内存。然后实现运算符*(不会改变它的参数)将非常简单:

bignum operator*(bignum left, const bignum &right) const {
    return left *= right;
}

这种方法有两个优点:

  • * 和 *= 运算符中没有复制粘贴功能。
  • 如果使用*=,则无需复制左侧参数并为其分配内存。

【讨论】:

    猜你喜欢
    • 2020-01-14
    • 2014-06-18
    • 2017-08-13
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多