为什么我在C语言中按位右移结果不一样?
Why are the results different when I did bitwise right shift in C language?
为了理解位右移操作,我写了下面的代码,
unsigned long a = 0;
unsigned long b = 0xFFFFFFFF;
a = ~a; // now a is equal to b
a = a >> 1;
b = b >> 1;
printf("a = %x\n", a); // result: a = 0xFFFFFFFF
printf("b = %x\n", b); // result: b = 0x7FFFFFFF
我虽然在右移操作前a和b都等于0xFFFFFFFF
,然后在右移后结果应该是相同的。但是结果显示
a = 0xFFFFFFFF
b = 0x7FFFFFFF
好像a的最高位是1,而b的最高位是0,为什么会这样?
如果您修复了错误的说明符并添加了一些额外的打印输出,您会发现您的假设是错误的:
#include <stdio.h>
int main(void) {
unsigned long a = 0;
unsigned long b = 0xFFFFFFFF;
printf("a = %lx\n", a);
printf("b = %lx\n", b);
a = ~a; // now a is equal to b
printf("a == b? %s\n", a == b ? "Yes" : "No");
printf("a = %lx\n", a);
printf("b = %lx\n", b);
a = a >> 1;
b = b >> 1;
printf("a = %lx\n", a); // result: a = 0xFFFFFFFF
printf("b = %lx\n", b); // result: b = 0x7FFFFFFF
}
输出:
$ ./a.out
a = 0
b = ffffffff
a == b? No
a = ffffffffffffffff
b = ffffffff
a = 7fffffffffffffff
b = 7fffffff
记得用 -Wall -Wextra
编译来捕获这样的错误。
解决方法:改为:unsigned long b = -1;
另一种解决方法:包含limits.h
并使用ULONG_MAX
.
值得注意的是long
没有固定的宽度。如果你想要固定宽度,那么使用像 uint32_t
.
这样的类型
为了理解位右移操作,我写了下面的代码,
unsigned long a = 0;
unsigned long b = 0xFFFFFFFF;
a = ~a; // now a is equal to b
a = a >> 1;
b = b >> 1;
printf("a = %x\n", a); // result: a = 0xFFFFFFFF
printf("b = %x\n", b); // result: b = 0x7FFFFFFF
我虽然在右移操作前a和b都等于0xFFFFFFFF
,然后在右移后结果应该是相同的。但是结果显示
a = 0xFFFFFFFF
b = 0x7FFFFFFF
好像a的最高位是1,而b的最高位是0,为什么会这样?
如果您修复了错误的说明符并添加了一些额外的打印输出,您会发现您的假设是错误的:
#include <stdio.h>
int main(void) {
unsigned long a = 0;
unsigned long b = 0xFFFFFFFF;
printf("a = %lx\n", a);
printf("b = %lx\n", b);
a = ~a; // now a is equal to b
printf("a == b? %s\n", a == b ? "Yes" : "No");
printf("a = %lx\n", a);
printf("b = %lx\n", b);
a = a >> 1;
b = b >> 1;
printf("a = %lx\n", a); // result: a = 0xFFFFFFFF
printf("b = %lx\n", b); // result: b = 0x7FFFFFFF
}
输出:
$ ./a.out
a = 0
b = ffffffff
a == b? No
a = ffffffffffffffff
b = ffffffff
a = 7fffffffffffffff
b = 7fffffff
记得用 -Wall -Wextra
编译来捕获这样的错误。
解决方法:改为:unsigned long b = -1;
另一种解决方法:包含limits.h
并使用ULONG_MAX
.
值得注意的是long
没有固定的宽度。如果你想要固定宽度,那么使用像 uint32_t
.