在C++中使用uint16_t左移uint64_t时出现奇怪的错误。

huangapple go评论72阅读模式
英文:

Strange error when bit shifting uint64_t by a uint16_t in cpp

问题

下面的函数试图通过将0x1左移N次来创建一个位板,其中设置的位位于第N个位置N由uint16_t中的第1到6个最低有效位给出。然后通过掩码来隔离6个最低有效位。

```c
uint64_t endSquareFinder(uint16_t a){
    a &= 0x003f;
    return 0x0000000000000001 << a;
}

所有输入都有效,除了当a = 0x001f时,函数的输出为0xffffffff80000000,而不是0x0000000080000000。这对我来说非常奇怪。


<details>
<summary>英文:</summary>

The function below is attempting to create a bitboard with the set bit being in the Nth position, by bitshifting 0x1  N times to achieve desired result. N is being given by the 1-6th least significant bits in a uint16_t. It is then masked to isolate 6 lsbs.

uint64_t endSquareFinder(uint16_t a){
a &= (0x003f);
return 0x0000000000000001 << a;
}


All inputs work except for when a = 0x001f, the output of the function is 0xffffffff80000000 rather than 0x0000000080000000. This to me is very bizare.

gdb compiler

</details>


# 答案1
**得分**: 6

需要将`1`转换为一个无符号64位整数。现在它是一个`int`...
```c++
#include <type_traits>
// 这个通过了:
static_assert(std::is_same_v<decltype(0x0000000000000001), int>);

... 这很可能只有32位。

示例:

return std::uint_least64_t(1) << a;
// 或者
return 1ull << a; // "unsigned long long int" 至少有64位
英文:

You need to make 1 into an unsigned 64 bit integer. Right now it's an int ...

#include &lt;type_traits&gt;
// this passes:
static_assert(std::is_same_v&lt;decltype(0x0000000000000001), int&gt;);

... which is most likely only 32 bits.

Example:

return std::uint_least64_t(1) &lt;&lt; a;
// or
return 1ull &lt;&lt; a; // &quot;unsigned long long int&quot; is at least 64 bits

huangapple
  • 本文由 发表于 2023年7月7日 01:37:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76631302.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定