这是代码段。它的表现x/2^n
,四舍五入到0。第一个 print 语句计算正确的值(在本例中为 -7),但第二个语句,即第一个语句,bias
替换为 ((x>>31) & ((1<<n)+0xffffffff))
(无论如何偏差正在计算什么)并生成 9。这是怎么回事?
#include <stdio.h>
int main(void) {
int x = 0x80000004;
int n = 0x1c;
int bias = ((x>>31) & ((1<<n)+0xffffffff));
printf("%dn", (x + bias) >> n);
printf("%dn", (x + ((x>>31) & ((1<<n)+0xffffffff))) >> n);
return 0;
}
表达式
x + bias
和x + ((x>>31) & ((1<<n)+0xffffffff))
有不同的类型;第一个是int
,第二个是unsigned int
。运算符>>
保留符号位 int
秒,但不保留 unsigned
秒的符号位。(编译器不必这样做,但它可以这样做。为了清楚地了解发生了什么,我稍微扩展了代码:
#include <stdio.h>
int main(void) {
int x = 0x80000004;
int n = 0x1c;
int bias = ((x>>31) & ((1<<n)+0xffffffff));
printf("%dn", (x + bias) >> n);
printf("%dn", (x + ((x>>31) & ((1<<n)+0xffffffff))) >> n);
printf("%dn", (x + (int)((x>>31) & ((1<<n)+0xffffffff))) >> n);
printf ("(int) %dn", x + bias);
printf ("(unsigned) %un", x + ((x>>31) & ((1<<n)+0xffffffff)));
return 0;
}
输出为:
-7
9
-7
(int) -1879048189
(unsigned) 2415919107