制作uint128库并不能,找出是什么功能搞砸了

时间:2019-04-15 03:01:07

标签: c++

我正在上一堂课,我想我大部分时间都在正常工作,但是这个部门让我很沮丧。我主要负责的部分是从这里得到的。不幸的是,我无法获得部门代码来与我的班级一起工作。它可以在uin64上正常工作,我不知道我班的哪一部分不起作用。

我在代码中发现了许多错误,并进行了修复。我还对除法功能所依赖的代码进行了彻底的测试,但仍然无法正常工作

class uint128_t {
public:
    unsigned long long int data[2];
    uint128_t() {
        data[1] = 0;
        data[0] = 0;
    }
    uint128_t operator~() {
        uint128_t out;
        out.data[0] = ~data[0];
        out.data[1] = ~data[1];
        return out;
    }
        uint128_t operator+(const uint128_t& b) {
        uint128_t out;
        out.data[1] = data[1] + b.data[1];
        out.data[0] = data[0] + b.data[0];
        if (b.data[0] > (UINT8_MAX - data[0]))out.data[1]++;
        return out;
    }
    uint128_t operator+(const unsigned long long int& b) {
        uint128_t out;
        out.data[1] = data[1];
        out.data[0] = data[0] + b;
        if (b > (UINT64_MAX - data[0]))out.data[1]++;
        return out;
    }
    uint128_t operator-(const uint128_t& b) {
        uint128_t out;
        out.data[1] = data[1] + ~b.data[1];
        out.data[0] = data[0] + ~b.data[0];
        if (b.data[0] > (UINT8_MAX - data[0]))out.data[1]++;
        out.data[0]++;
        out.data[1]++;
        return out;
    }
    bool operator<(const uint128_t& b) {
        if (data[1] == b.data[1]) {
            return (data[0] < b.data[0]) ? true : false;
        }
        else return (data[1] < b.data[1]) ? true : false;
    }   
        bool operator>=(const uint128_t& b) {
        if (data[1] == b.data[1]) {
            return (data[0] >= b.data[0]) ? true : false;
        }
        else return (data[1] > b.data[1]) ? true : false;
    }
    uint128_t &operator=(const int& b) {
        data[1] = 0;
        data[0] = b;
        return *this;
    }
    uint128_t& operator=(const uint128_t& b) {
        data[1] = b.data[1];
        data[0] = b.data[0];
        return *this;
    }
};

int main()
{

    uint128_t divisor;
    divisor = 2;
    uint128_t quot, rem, t;
    int bits_left = 128;

    quot = 128;
    rem = 0;
    do {
        // (rem:quot) << 1
        t = quot;
        quot = quot + quot;
        rem = rem + rem + (quot < t);

        if (rem >= divisor) {
            rem = rem - divisor;
            quot = quot + 1;
        }
        bits_left--;
    } while (bits_left);
    std::cout << std::bitset<64>(quot.data[1]) << std::bitset<64>(quot.data[0]) << std::endl;
}

所以128(quot)/ 2(divisor)= 64,但是每次我运行它时,我都会有些胡言乱语。但是,如果我将类型从我的班级更改为uint64,就可以正常使用

1 个答案:

答案 0 :(得分:2)

您应该在多个地方使用UINT8_MAX来代替UINT64_MAXoperator+是其中一种情况。

uint128_t operator+(const uint128_t& b) {
    uint128_t out;
    out.data[1] = data[1] + b.data[1];
    out.data[0] = data[0] + b.data[0];
    if (b.data[0] > (UINT8_MAX - data[0]))out.data[1]++;
    //               ^^^^^^^ here
    // should be UNIT64_MAX
    return out;
}

uint128_t operator-(const uint128_t& b) {
    uint128_t out;
    out.data[1] = data[1] + ~b.data[1];
    out.data[0] = data[0] + ~b.data[0];
    if (b.data[0] > (UINT8_MAX - data[0]))out.data[1]++;
    //               ^^^^^^^ here
    // should be UNIT64_MAX
    out.data[0]++;
    out.data[1]++;
    return out;
}

编写big-int或int128可能是一种很好的学习体验,但是您应该意识到现有的库也可以做到这一点,例如boost int128_t

此外,编写一组简单的单元测试。每次单元测试最多一次检查一名操作员。检查有趣的情况,例如添加几乎需要进位的值,几乎不需要进位的值,等等。这样的测试会发现这些错误要容易得多。