我最近发现在 C 中将变量设置为全 1 的两种方法之间存在差异。 这是一个小代码示例,用于说明我的 64 位 Linux 系统上的奇怪行为。
// compile with `gcc -o weird_shift_behaviour weird_shift_behaviour.c`
#include <stdio.h>
int main(void){
long long foo = 0;
long long bar = 0;
int i;
puts("<foo> will be set to all 1s by repeatedly shifting 1 to the left and OR-ing the result with <foo>.");
puts("<bar> will be set to all 1s by repeatedly OR-ing it with 1 and shifting <bar> to the left one step.");
for(i=0;i<8*(int)sizeof(long long)-1;++i){
foo |= (1<<i);
bar = bar<<1 | 1;
printf("<i>: %02d <foo>: %016llx <bar>: %016llx \n",i,foo,bar);
}
return 0;
}
我确实知道这不是在 C 中将整数类型设置为全 1 的规范方法,但我还是尝试过。以下是示例程序生成的输出中有趣的部分:
<i>: 29 <foo>: 000000003fffffff <bar>: 000000003fffffff
<i>: 30 <foo>: 000000007fffffff <bar>: 000000007fffffff
<i>: 31 <foo>: ffffffffffffffff <bar>: 00000000ffffffff
<i>: 32 <foo>: ffffffffffffffff <bar>: 00000001ffffffff
为什么会出现这种奇怪的行为?到目前为止,我想不出任何合理的解释。
最佳答案
1<<i
1
类型为 int
和 1 << 31
当 int
时是未定义的行为是 32 位宽。
来自 C 标准:
(C99, 6.5.7p4) "The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. [...] If E1 has a signed type and nonnegative value, and E1 x 2 ^ E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined."
要解决您的问题,请更改 1<<i
与 1ULL << i
.
关于c - 为什么这两种将变量设置为全 1 的方法会导致不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21525495/