c++ - unsigned long long 溢出错误?

标签 c++ visual-c++ integer-overflow unsigned-long-long-int

我在使用 unsigned long long 时遇到了一些奇怪的问题。

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

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

//Outputs 18446744071562067968, Expected 2147483648

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

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

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

最佳答案

当负整数值分配给 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;会工作。我只是希望尽可能明确。

关于c++ - unsigned long long 溢出错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23976201/

相关文章:

C++ If 语句,从 else 开始重复

c++ - 错误 C2220 : warning treated as error-no 'object' file generated in driver development

visual-studio - 将弃用/clr :oldSyntax supported in VS2005 and VS2008 still work with VS2010?

c++ - 将非托管 C++ dll 添加到托管 C++ dll

java - 为什么使用 i*i < n 的 isPrime 为除 2^31- 1 之外的每个 int 返回正确答案

c++ - 模板参数的格式规范

C++:互斥和释放

visual-studio - Visual Studio Profiler 将 "[broken]"显示为函数名称

c++ - 在不同 CPU 上处理整数

C 操作无符号整数 - 整数溢出