3

我在 unsigned long long 方面遇到了一些奇怪的问题。

当我设置一个 unsigned long long 时会发生这种情况(我使用了 size_t,但是这个问题可以用 ull 重复)。我已将其设置为 2^31,但由于某种原因,它恢复为 18446744071562067968 或 2^64 - 2^31。请记住,我使用的是 x64 编译:

unsigned long long a = 1 << 31;
cout << a;

//Outputs 18446744071562067968, Expected 2147483648

我以为 ull 的极限是 2^64-1?那么为什么不能存储 2^31 呢?2^30 工作得很好。Sizeof(a) 返回 8,如果我没记错的话是 64 位,证明了 2^64-1 的限制。

我正在 Visual C++ 2013 Express Desktop 上编译。

我唯一的猜测是它是某种类型的溢出错误,因为它不适合正常的 long 类型。

4

1 回答 1

2

当负整数值分配给 unsigned long long 时,您看到的是符号扩展。

要修复它,您需要将值设为无符号开头,如下所示:

#include <iostream>
#include <iomanip>

int main()
{
    unsigned long long a = 1ull << 31ull;
    std::cout << a << "\n";
    std::cout << std::hex << a << "\n";

    return 0;
}

如果您将警告级别设置得足够高(/W4),您会看到有关有符号/无符号不匹配的警告。

为了完整起见,您不需要限定两个参数,只需左操作数就可以了,这样unsigned long long a = 1u << 31;就可以了。我只是更喜欢尽可能明确。

于 2014-06-01T02:33:30.583 回答