在 C 中链接移位运算符后出现意外结果
Unexpected result after chaining bit-shift operators in C
我不明白为什么链接移位操作返回的结果与不链接它们的结果不同。
#include <stdio.h>
void bit_manip_func(unsigned char byte)
{
unsigned char chain = (((byte >> 3) << 7) >> 3);
printf("%d\n", chain); //this prints 144
unsigned char o1 = byte >> 3;
unsigned char o2 = o1 << 7;
unsigned char o3 = o2 >> 3;
printf("%d\n", o3); //this prints 16 as expected
}
int main()
{
//expecting both printf's to print
//the same value (16).
bit_manip_func(73);
return 0;
}
我希望 printf
调用都打印出 16,因为二进制中的 73 是 0100 1001。在应用 byte >> 3
之后我应该得到 0000 1001,在 (byte >> 3) << 7
之后结果应该是 1000 0000,在 (((byte >> 3) << 7) >> 3)
之后结果应该是 0001 0000,当然是 16。实际发生了什么?
在
unsigned char chain = (((byte >> 3) << 7) >> 3);
((byte >> 3) << 7)
被提升为 int
,然后它在 int
上执行 >> 3
包装成 unsigned char
(mod 256) 你得到 ((73 >> 3) << 7) >> 3) % 256
= 144
使用强制转换:
unsigned char chain = ((unsigned char)((byte >> 3) << 7) >> 3);
运算符 >> 和 << 对其操作数执行整数提升。因此,当与任一运算符一起使用时,类型 unsigned char 被提升为 int。
在下面一行中,变量byte被提升为int类型,然后三个操作都在这个类型上进行:
unsigned char chain = (((byte >> 3) << 7) >> 3);
因此保留设置为 1 的最左边的位:
01001001 => 01001 => 010010000000 => 010010000
^ ^ ^ ^
在下面的代码中,变量被提升为 int 类型,但在每次操作之后,具有 int 类型的结果被分配给一个 unsigned char 并因此换行(最高有效位被删除),
因为 unsigned char 的范围在您的平台上是 [ 0 , 2^8-1 ]。
unsigned char o1 = byte >> 3;
unsigned char o2 = o1 << 7;
unsigned char o3 = o2 >> 3;
这意味着设置为 1 的最左边的位未保留:
01001001 => 01001 => 10000000 => 000010000
^ ^
我不明白为什么链接移位操作返回的结果与不链接它们的结果不同。
#include <stdio.h>
void bit_manip_func(unsigned char byte)
{
unsigned char chain = (((byte >> 3) << 7) >> 3);
printf("%d\n", chain); //this prints 144
unsigned char o1 = byte >> 3;
unsigned char o2 = o1 << 7;
unsigned char o3 = o2 >> 3;
printf("%d\n", o3); //this prints 16 as expected
}
int main()
{
//expecting both printf's to print
//the same value (16).
bit_manip_func(73);
return 0;
}
我希望 printf
调用都打印出 16,因为二进制中的 73 是 0100 1001。在应用 byte >> 3
之后我应该得到 0000 1001,在 (byte >> 3) << 7
之后结果应该是 1000 0000,在 (((byte >> 3) << 7) >> 3)
之后结果应该是 0001 0000,当然是 16。实际发生了什么?
在
unsigned char chain = (((byte >> 3) << 7) >> 3);
((byte >> 3) << 7)
被提升为 int
,然后它在 int
>> 3
包装成 unsigned char
(mod 256) 你得到 ((73 >> 3) << 7) >> 3) % 256
= 144
使用强制转换:
unsigned char chain = ((unsigned char)((byte >> 3) << 7) >> 3);
运算符 >> 和 << 对其操作数执行整数提升。因此,当与任一运算符一起使用时,类型 unsigned char 被提升为 int。
在下面一行中,变量byte被提升为int类型,然后三个操作都在这个类型上进行:
unsigned char chain = (((byte >> 3) << 7) >> 3);
因此保留设置为 1 的最左边的位:
01001001 => 01001 => 010010000000 => 010010000
^ ^ ^ ^
在下面的代码中,变量被提升为 int 类型,但在每次操作之后,具有 int 类型的结果被分配给一个 unsigned char 并因此换行(最高有效位被删除),
因为 unsigned char 的范围在您的平台上是 [ 0 , 2^8-1 ]。
unsigned char o1 = byte >> 3;
unsigned char o2 = o1 << 7;
unsigned char o3 = o2 >> 3;
这意味着设置为 1 的最左边的位未保留:
01001001 => 01001 => 10000000 => 000010000
^ ^