我正在上一堂课,我想我大部分时间都在正常工作,但是这个部门让我很沮丧。我主要负责的部分是从这里得到的。不幸的是,我无法获得部门代码来与我的班级一起工作。它可以在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
,就可以正常使用
答案 0 :(得分:2)
您应该在多个地方使用UINT8_MAX
来代替UINT64_MAX
。 operator+
是其中一种情况。
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。
此外,编写一组简单的单元测试。每次单元测试最多一次检查一名操作员。检查有趣的情况,例如添加几乎需要进位的值,几乎不需要进位的值,等等。这样的测试会发现这些错误要容易得多。