如何正确取消64位数位?

时间:2017-07-24 05:49:53

标签: c++ bit

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

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

     

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

但最后一个改变了,不应该包括所有的那些。

2 个答案:

答案 0 :(得分:8)

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

如果您想使用uint64_t,请务必执行此操作。

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

或只是

a |= (1ULL<<i);

会做到这一点。

答案 1 :(得分:5)

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

明显的原因是(1<<i)是一个int,因为常量1是一个int。 (有符号类型)超出位限制的移位操作未定义。

所以你需要强制表达式为std::uint64_t。一个这样的方式是这样的:

constexpr std::uint64_t one = 1;

// ...

for (unsigned i = 0; i <= 52; i++)
  a |= (one << i);