C++ 按位左移 32

C++ bitwise left shift by 32

目前我正在研究背包问题的蛮力算法。一切都适用于小问题实例,例如 15 个项目。但是当我 运行 我的程序针对更大的实例(如 31 或 32)时,算法失败了。我 运行 遇到了按位移位的问题,我用它来计算可能的解决方案的数量。例如,对于 10 个项目,程序应该进行 2^10 次迭代,所以我使用这个语句:

unsigned long long int setCnt = (1 << 10);

计算值1024是正确的。但是对于 (1 << 31),计算值是 18446744071562067968(最大值 unsigned long long int),但应该是 2147483648。(1 << 32) returns 0。这就像从 0 到 30 的一切都正常位。

我正在使用 Visual Studio 2015 社区并在 x64 模式下编译我的解决方案。 是什么导致了这种行为?我怎样才能避免这个?

问题是 1 是一个 signed int 常量字面量——所以移位是作为 signed int 移位完成的(这显然只有 32 位,包括你的符号编译器),所以它会溢出,导致未定义的行为。

尝试使用 1ULL << 32(或您想要的任何其他偏移量)- ULL 后缀使常量成为 unsigned long long,匹配您想要的结果的类型。如果移位量对于 unsigned long long 来说太大,这可能仍然会溢出,但在此之前它会起作用。