C 位移位问题

C 位移位问题,c,bit-manipulation,C,Bit Manipulation,如果我有int temp=(131)。为什么temp变成-1? 我该如何避开这个问题? 谢谢int已签名 什么‘问题’——你想做什么 int i = (1<<31); // i = -2147483648 i>>31; // i = -1 unsigned int i = (1<<31); // i = 2147483648 i>>31; // i = 1 inti=(131;//i=-1 无符号整数i=(131;//i=1 ps是一个很

如果我有int temp=(131)。为什么temp变成-1? 我该如何避开这个问题? 谢谢

int已签名

什么‘问题’——你想做什么

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

unsigned int i = (1<<31); // i = 2147483648
i>>31;  // i = 1
inti=(131;//i=-1
无符号整数i=(131;//i=1

ps是一个很好的windows命令行“c”intepreter,它允许您在不编译的情况下尝试这类东西,它还提供了一个unix命令shell。请参见

在您的示例中,表达式中的
1
是有符号类型-因此,当您将其升档31时,其符号会发生变化。然后,降档会导致符号位重复,并且以
0xffffffff
的位模式结束

您可以这样修复它:

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

如果您启用了
-Wall
,GCC会警告此类错误。

当您启用
(1时,默认情况下,整数是有符号的,这通常意味着保留高位以指示整数是否为负。请查阅此操作的说明

结果如下:

[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
[steven@sexy:~]%cat test.c
#包括
#包括
int main(int argc,字符**argv[]{
uint32_t uint;
int32_t sint;
国际贸易;
uint=((uint32_t)1)31;
sint=(1 31;
slong=(1L>31;
printf(“已签名的32=%d,未签名的32=%u,已签名的64=%ld\n”,sint,uint,slong);
}
[steven@sexy:~]%/测试
有符号32=-1,无符号32=1,有符号64=1

请注意,您可以通过使用“unsigned”int(允许使用所有32位)或转到不溢出的更大类型来避免此问题。

位表示在执行此操作时设置了符号“”整型变量的左移位。结果就是这样。

我检查了符号扩展的描述,但我看不出它与OP观察到的现象有什么关系。问题是,在他的实现中,右移位是算术移位,int是有符号的,32位长。@Maciej,看起来你是对的-我误用了ter我在这里。我将编辑以澄清这一点。还要特别注意,有符号值的右移取决于编译器。因此,这里看到的输出仅适用于特定平台,其他平台可能会给出其他结果。这是事实,但这不会使使用无符号或更长变量的修复无效。我认为。