C++中64位整数的按位(移位)操作

13

我正在尝试处理位棋盘,这要求我在64位无符号整数中设置特定的位。为了设置第i位,我执行一次按位或运算,将目标位棋盘与左移后的数字相结合。

#include <stdint.h>
uint64_t kings = 0ULL; // Also tried unsigned long long int before.
kings |= 1 << i;

它在0到31位上工作得很好,但在32到63位上无法工作。我怀疑这是因为右侧的评估恰好发生在一个32位整数中。因此,我尝试了一个临时变量。

uint64_t temp = 0ULL;
temp |= 1 << i;

也许它仍然将右侧视为32位整数,或者我无法想出其他问题。为了输出整数,我正在使用std::bitset<64>。例如:

uint64_t kings = 0ULL;
kings |= 1 << 3;
kings |= 1 << 59;

期望的十进制值:576460752303423496

实际值:8

std::bitset<64> x(kings);
std::cout << x;

位值:0000000000000000000000000000000000000000000000000000000000001000

显然,只有"kings |= 1 << 3;" 才能正确工作。

总之,问题是位32到63,我该如何解决?


2
你尝试过使用 'kings |= (uint64_t)1 << (uint64_t)i;' 或者 'kings |= 1ULL << i;' 吗? - Danny Ruijters
@DannyRuijters 没有考虑到。我试图将其等同于临时 uint64_t。接近了! - Shreyas
3个回答

25

在使用左移运算符 << 生成 64 位结果之前,您需要将其作为 64 位值使用 1LL:

#include <stdint.h>
uint64_t kings = 0ULL; 
kings |= 1ULL << i;

9

32到63位有什么问题?

字面量1的类型是int。移位运算符的结果类型是其左操作数的类型(在进行通常的算术转换后)。 在您的实现中,它似乎是32位,因此将其向左移动超过31位会导致未定义行为。

请使用64位整数作为移位运算符的左操作数:

temp |= static_cast<uint64_t>(1) << i;

3
您需要对一个64位整数进行位移操作:
kings |= 1i64 << 59;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接