如果我有int temp =(1<< 31)> 31。为什么临时变成-1? 我该如何解决这个问题? 感谢
答案 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”左移时,符号已设置。因此结果。