长时间计数位无法按预期工作

标签 c bitwise-operators tdm-mingw

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”。我做错了什么?

最佳答案

您对 1LL 的转移,已签名,产生 undefined behavior .因此,允许将 64 位有符号整数移位 63 位,让编译器做一些有趣的事情(比如 making daemons fly out of your nose)。

解决方案是使用1ULL << x而不是在这种情况下。

另见 this excellent article来自 LLVM 的 Chris Lattner,他解释了为什么这样的事情会导致奇怪的行为。

关于长时间计数位无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6540026/

相关文章:

php - MySQL 在 WHERE 语句中按位返回奇数结果

c - 在 C 或 CUDA 中使用 << 求幂

c - 在 C 编程中,宏从不进行类型检查?那么0x01和0x01u定义宏有什么区别呢?

c - OpenMP - 在并行 for 循环中调用外部函数

c - 段错误(核心转储)- cPointers [C]

c++ - tdm gcc 5.1 比 4.7 慢

c - 管道传输时程序输出发生变化

java - 按位运算符的澄清

c++ - Mingw-w64 和 TDM-GCC 一个简单的 GDI 项目的区别