计算 long long 中的位未按预期工作
uint64_t bitsToInt64(char *bs) {
uint64_t r, i;
r = 0;
for(i = 0; i < 64; i++)
if(bs[i] == 1)
r |= 1LL << i;
return r;
}
int countBits64(uint64_t i) {
uint64_t x, t;
t = 0LL;
for(x = 0LL; x < 64LL; x++) {
if(i & (1LL << x))
t += 1;
}
return t;
}
char bits [] = {
0, 0, 0, 0, 1, 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,};
uint64_t mask = bitsToInt64(bits);
int nbits = countBits64(mask);
printf("%d", nbits);
上面是打印“1”。我做错了什么?
uint64_t bitsToInt64(char *bs) {
uint64_t r, i;
r = 0;
for(i = 0; i < 64; i++)
if(bs[i] == 1)
r |= 1LL << i;
return r;
}
int countBits64(uint64_t i) {
uint64_t x, t;
t = 0LL;
for(x = 0LL; x < 64LL; x++) {
if(i & (1LL << x))
t += 1;
}
return t;
}
char bits [] = {
0, 0, 0, 0, 1, 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,};
uint64_t mask = bitsToInt64(bits);
int nbits = countBits64(mask);
printf("%d", nbits);
The above is printing "1". What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您对已签名的
1LL
进行移位会产生 未定义行为。因此,将 64 位有符号整数移位 63 位可以让编译器做一些有趣的事情(例如 让恶魔从你的鼻子里飞出来)。解决方案是使用
1ULL <<在本例中改为 x
。另请参阅这篇优秀文章,来自LLVM 的 Chris Lattner 解释了为什么这样的事情会导致奇怪的行为。
Your shifting of
1LL
, which is signed, yields undefined behavior. Shifting a 64bit signed integer by 63 bits is thus allowed to make the compiler do funny things (like making daemons fly out of your nose).The solution is to use
1ULL << x
instead in this case.See also this excellent article from an Chris Lattner of LLVM that explains why things like this can result in strange behavior.
使用下面的代码我能够得到以下输出
确保使用正确的大小值。文字常量需要
ULL
以便与 uint64_t 匹配,for 循环变量只需为 int,以及countBits64
的返回值。With the code below I was able to get the following output
Make sure you use the correct size values. The literal constants need
ULL
so that they match uint64_t and the for loop variables only need to be an int, as well as the return value forcountBits64
.