【发布时间】:2017-11-04 19:33:30
【问题描述】:
考虑下面的代码,它在一个字节中交换半字节:
#include <stdio.h>
unsigned char swapNibbles(unsigned char x)
{
return ( (x & 0x0F)<<4 | (x & 0xF0)>>4 );
}
int main()
{
unsigned char x = 100;
printf("%u", swapNibbles(x));
return 0;
}
为什么需要用 0x0F 和 0xF0 进行与运算?相反,我可以写
return ((x<<4) | (x>>4));
我已经用谷歌搜索过它,人们似乎说它不适用于负数,因为它会用右移的数字填充数字但是与 0xF0 并不会使数字为正数? 我错过了什么?
【问题讨论】:
-
您什么都不会错过,
((x<<4) | (x>>4))会起作用(只要x是unsigned char)。 -
@HolyBlackCat: .... 并且 CHAR_BIT == 8。这是非常罕见的事情,但对于某些 DSP 微控制器可能并非如此,因此符合标准的代码需要
-
AFAIK 这就是 Java 的情况,因为 Java 字节总是有符号并符号扩展为整数。也许代码是由使用 Java 的人移植或编写的。
-
((x<<4) | (x>>4))实际上不会给出正确的结果,因为x在执行移位之前被提升为 int。只有在return中转换为无符号字符,我们才能得到正确的结果。 -
@FalkHüffner 它会起作用,因为
unsigned char总是零扩展为 int,而不是有符号扩展,因此高字节中没有 1
标签: c++ bit-manipulation