按位移位问题

时间:2010-07-08 17:49:40

标签: c bit-manipulation

如果我有int temp =(1<< 31)> 31。为什么临时变成-1? 我该如何解决这个问题? 感谢

5 个答案:

答案 0 :(得分:9)

默认情况下会对符号进行签名,这通常意味着保留高位以指示整数是否为负。查看Two's complement,了解其工作原理。

这是结果:

[steven@sexy:~]% cat test.c
#include <stdint.h>
#include <stdio.h>

int main(int argc, char **argv[]) {
    uint32_t uint;
    int32_t sint;
    int64_t slong;
    uint = (((uint32_t)1)<<31) >> 31;
    sint = (1<<31) >> 31;
    slong = (1L << 31) >> 31;
    printf("signed 32 = %d, unsigned 32 = %u, signed 64 = %ld\n", sint, uint, slong);
}

[steven@sexy:~]% ./test
signed 32 = -1, unsigned 32 = 1, signed 64 = 1

注意如何通过使用“unsigned”int(允许使用所有32位)或通过更大的类型来避免此问题。

答案 1 :(得分:5)

在您的情况下,表达式中的1是签名类型 - 因此当您将其升档31时,其符号会发生变化。然后降档导致符号位重复,最后得到0xffffffff的位模式。

你可以这样解决:

int temp = (1UL << 31) >> 31;

如果您-Wall已开启,GCC会发出此类错误警告。

答案 2 :(得分:1)

int已签名。

什么'问题' - 你想做什么?

int i = (1<<31); // i = -2147483648
i>>31;  // i = -1

unsigned int i = (1<<31); // i = 2147483648
i>>31;  // i = 1

ps ch是Windows的一个很好的命令行'c'解释器,可以让你在不编译的情况下尝试这种东西,它还为你提供了一个unix命令shell。见http://www.drdobbs.com/184402054

答案 3 :(得分:1)

执行(1<<31)时,设置符号位的MSB(变为1)。然后当你做右移时,它会被符号扩展。因此,你得到-1。溶液:(1UL&lt; 31)&gt; 31。

答案 4 :(得分:0)

位表示当您对整数变量执行“such”左移时,符号已设置。因此结果。