我有十六进制数0x8F
(二进制10001111)。我想右移那个值,所以新的值将是0xC7
(11000111)。我尝试过:
unsigned char x = 0x8F;
x=x>>1;
但不是0xC7我得到了0x47?关于如何做到这一点的任何想法?
答案 0 :(得分:14)
对未签名的数量进行右移会使新的零进入,而不是输入。
请注意,右移不是正确的轮换。要做到这一点,你需要
x = (x >> 1) | (x << 7)
答案 1 :(得分:8)
那是因为你想要的是一个&#34;向右旋转&#34;而不是&#34;向右移动&#34;。所以你需要调整最低位&#34;掉落&#34;:
x = ((x & 1) << CHAR_BITS-1) | (x >> 1);
应该这样做。
[并且至少有一些编译器会检测到这组特定的操作并转换为相应的ror
或rol
指令]
答案 2 :(得分:2)
右移或左移将分别在字节的左侧或右侧填充0
s。转移后,您需要OR
使用正确的值才能获得您期望的结果。
x = (x >> 1); /* this is now 01000111 */
x = x | ( 0x80 ); /* now we get what we want */
我在OR
10000000
使用0x80
字节0xC7
,结果为x = (x >> 1) | (unsigned char)0x80;
。
使它更简洁,它变成:
{{1}}