奇怪的位杂乱的bug

时间:2011-03-27 00:11:36

标签: c

我有一个简单的功能:

int bitcount( unsigned );

int shiftbit( unsigned val ) {
    return (int)(~0U << (( sizeof(int)*CHAR_BIT ) - bitcount(val)));
}

我正在计算int中的位数,然后创建一个具有左对齐位数的位掩码。例如,0xABCD设置了10位并返回掩码0xFFC0000。

该函数效果很好,除非bitcount为零,在这种情况下我得到-1,0xffffffff,当我应该得到一个空的位掩码,即0x0。我不清楚为什么它应该适用于除零之外的每一个案例。

答案

所以我最终改变了如下代码,它工作正常并且应该是可移植的:

int shiftbit( unsigned val ) {
    int bCount = bitcount(val);
    return bCount ? (~0 << (( sizeof(int)*CHAR_BIT ) - bCount)) : 0;
}

3 个答案:

答案 0 :(得分:9)

如果移位的位数大于或等于移位值中的位数,则移位操作的结果是不确定的。因此,将32位值移位32不能保证特别产生任何东西。

答案 1 :(得分:4)

因为在C中,如果将大小为x位的操作数移位x位,则结果是未定义的。因此,例如1 << 32未定义(假设为sizeof(int) == 4

答案 2 :(得分:0)

在C中,移位的结果取决于实现。使用x86处理器,您实际上可以确保移位操作数是模32(在32位模式下)。请参阅本文档的第3-623页:

ftp://download.intel.com/design/intarch/manuals/24319101.pdf

“目标操作数可以是寄存器或内存位置。计数操作数可以是 立即价值或登记CL。 计数被屏蔽为五位,这会限制计数范围 从0到31.为1“

的计数提供特殊的操作码编码