byte >> 4 | (byte & 0x0F) << 4
我在网上发现的其他解决方案是相似的,但是通过掩盖字节的左鼻子来增加一个额外的操作数:(byte & 0xF0) >> 4 | (byte & 0x0F) << 4
在二进制中,第二个解决方案看起来像这样:
# Extract the right nibble of a byte and shift to the left
[0xF5] 1111 0101 # Original Value
[0x0F] 0000 1111 & # Mask Right Nibble
[0x05] 0000 0101 = # Extracted Right Nibble
[0x50] 1010 0000 << 4 # Shift Four Bits to the Left
# Extract the left nibble of a byte and shift to the right
[0xF5] 1111 0101 # Original Value
[0xF0] 1111 0000 & # Mask Left Nibble
[0xF0] 1111 0000 = # Extracted Left Nibble
[0x0F] 0000 1111 >> 4 # Shift Four Bits to the Right
# Combine the shifted nibbles together
[0x05] 0000 1111 # Left Nibble Shifted to the Right
[0xF0] 0101 0000 | # Right Nibble Shifted to the Left
[0xF5] 0101 1111 = # New Value
# Bits shift into the least significant byte without masking
[0x0AF5] 0000 1010 1111 0101
[0x00AF] 0000 0000 1010 1111 >> 4
另一方面,如果您真正与一个字节一起工作,则不会掩盖左鼻子冗余,因为左nibble位会在右移动四个位后被归零吗?
[0xF5] 1111 0101
[0x0F] 0000 1111 >> 4
我在正确的位置有我的头,还是我应该考虑的东西?这里是进一步澄清的示例代码:
typedef uint8_t byte;
static inline
byte swap_nibbles(byte bits) {
return bits >> 4 | (bits & 0x0F) << 4;
}
您不显示
byte
的定义。如果它具有签名的八位整数,则此代码:
signed char byte = -111; /* 0x91 */
printf("0x%hhX\n", byte);
byte = byte >> 4 | (byte & 0x0F) << 4;
printf("0x%hhX\n", byte);
Prints:
0x91 0xf9
尽管最初包含位9116
byte
中,它被提升为
byte >> 4
。由于这些位代表值-111的值,因此以该值产生一个值,即具有四字节int
,ffffff9116
。然后
int
产生ffffff916
。用10
16从
int
产生FFFFFF916,然后将其分配给
>> 4
将其转换为|
。这是实现定义的,但最常见的结果是包裹模量256,产生位f916,代表值-7.。 在对比中,使用
byte
印刷:
0x91
0x19
,如果signed char
有未签名的八位整数类型,那么对byte = (byte &0xF0) >> 4 | (byte & 0x0F) << 4;
的促销不是问题,因为byte
有足够的净空,可以在这些表达式中保存这些值而不会遇到符号或溢出问题。