如何正确取消设置64位数字中的位?

How to correctly unset bits in 64 bit number?

本文关键字:数字 64位 何正确 取消 设置      更新时间:2023-10-16

我想设置所有,64位数字的一部分或不设置位。但是,当我打印位表示时,例如我只设置了 53 位,我看到所有位都是 1s。可能是什么问题?

int main() {
uint64_t a = 0;
for (int i = 0; i <= 63; i++)
std::cout<<((a>>i) & 0x01)<<" ";
std::cout<<std::endl;
for (unsigned i = 0; i <= 52; i++)
a |= (1<<i);
for (int i = 0; i <= 63; i++)
std::cout<<((a>>i) & 1)<<" ";
std::cout<<std::endl;
}

编辑: 我得到这个输出:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

但是最后一个,改变的,不应该包含所有的。

1是类型int的文本。如果计算机具有 32 位int,则(1<<i)会为所有大于 30i调用未定义的行为。

如果要使用uint64_t,请始终如一地这样做。

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

或者干脆

a |= (1ULL<<i);

会做这个伎俩。

程序的行为未定义。因此,无论您看到什么结果,就C++而言都是完全有效的。

原因很简单,(1<<i)是一个 int,因为常量 1 是一个 int。并且对超过位限制的 int(有符号类型(的移位操作是未定义的。

所以你需要强制表达式std::uint64_t.一种这样的方式是这样的:

constexpr std::uint64_t one = 1;
// ...
for (unsigned i = 0; i <= 52; i++)
a |= (one << i);