我正在尝试更改一个字节的4个中间位以对应另一个字节的高半字节:
假设我们从以下开始:
In = 0bABCDEFGH
Out = 0bXXXXXXXX // Some random byte
我想要:
Out = 0bXXABCDXX
使Out
极端情况下的所有其他位保持不变。
我该怎么做?
注意:“ X”代表0或1的任何位,只是为了区分来自输入的内容。
我必须:
(0b00111100 & (IN>>2)) = 0b00ABCD00
,它过滤高半字节并将其居中,但是那又如何呢?如何将其移至Out
?
答案 0 :(得分:6)
简单:
out &= 0b11000011;
out |= (in >> 2 & 0b00111100);
out &= 0b00111100
将out
设置为0bxx0000xx
,保留2个最高有效位和2个最低有效位。 in >> 2
将输入移位2,从而得到0xYYABCDEF
,YY
可以是00
或11
,具体取决于A
是什么。为了摆脱YY
和EF
,我们要做& 0b00111100
。
@JB 0B
所指的不是标准符号,因此您应该使用其他名称,最好是十六进制0x
符号。有关更多信息,请参见this。
因此使用十六进制将是:
out &= 0xC3;
out |= (in >> 2 & 0x3C)
这是转换表
`0xf` is `0b1111`
`0x3` is `0b0011`
`0xc` is `0b1100`
答案 1 :(得分:5)
假设in
和out
是unsigned char
,并且那个CHAR_BIT == 8
:
out = (out & 0xC3) | ((in >> 2) & 0x3C);
即总共进行了4次操作。
答案 2 :(得分:2)
有多种选择。从高角度来看,您可以
Out
的四个中间位关闭,如问题所示从In
准备一个掩码,并通过按位或将Out
和掩码合并(|
)Out
的四个中间位 off ,按照问题中的说明从In
准备一个掩码,并通过按位独占将Out
和掩码合并或(^
)Out
的四个中间位上,从In
准备一个掩码,类似于您现在的操作,但将外部位打开,然后合并{{ 1}}并通过按位与(Out
)通过按位与并使用在您要关闭的位置(仅)具有0的掩码实现强制关闭位。
通过在您要打开的位置(仅)上具有1s的掩码进行按位“或”来实现强制位打开。
您似乎已经掌握了转移的技巧,但是如果碰巧要转移带符号类型的对象,则确实需要小心。尽可能使用无符号类型进行位操作。