简体   繁体   English

在 C 中更改一个字节的 4 个中间位

[英]Change 4 middle bits of a byte in C

I'm trying to change the 4 middle bits of a byte to correspond to the High nibble of another byte:我正在尝试更改一个字节的 4 个中间位以对应于另一个字节的高半字节:

Suppose we start with:假设我们开始:

In = 0bABCDEFGH
Out = 0bXXXXXXXX // Some random byte

I want:我想要:

Out = 0bXXABCDXX

Leaving whatever other bits were in Out 's extremes unchanged.Out极端中的任何其他位保持不变。

How can I do this?我怎样才能做到这一点?

Note: The 'X' represents any bit, 0 or 1, just to distinguish what came from the input.注意: 'X' 代表任何位,0 或 1,只是为了区分来自输入的内容。

I got to:我必须:

(0b00111100 & (IN>>2)) = 0b00ABCD00

, which filters the high nibble and centers it but then what? ,它过滤了高半字节并将其居中,然后呢? How can I move it to Out ?我怎样才能把它移到Out

simple:简单的:

out &= 0b11000011;
out |= (in >> 2 & 0b00111100);

out &= 0b11000011 sets out to 0bxx0000xx preserving 2 most significant bits and 2 least significant bits. out &= 0b11000011out0bxx0000xx保存2最显著位和2至少显著位。 in >> 2 shifts input by 2 giving us 0xYYABCDEF , YY could be 00 or 11 depending on what A is. in >> 2将输入移动 2 给我们0xYYABCDEFYY可能是0011取决于A是什么。 To get rid of YY and EF we do & 0b00111100 .为了摆脱YYEF我们做& 0b00111100

As pointed by @JB 0B is not standard notation, thus you should use something else, most preferably hex 0x notation.正如@JB 0B所指出的那样,不是标准符号,因此您应该使用其他东西,最好是十六进制0x符号。 See this for more info.有关更多信息,请参阅内容。

Thus using hex this would be:因此使用十六进制这将是:

out &= 0xC3;
out |= (in >> 2 & 0x3C)

here is conversion table这是转换表

`0xf` is `0b1111`
`0x3` is `0b0011`
`0xc` is `0b1100`

Assuming in and out are unsigned char , and that CHAR_BIT == 8 :假设inoutunsigned char ,并且CHAR_BIT == 8

out = (out & 0xC3) | ((in >> 2) & 0x3C);

ie 4 operations in total.即总共 4 次操作。

There are multiple alternatives.有多种选择。 From a high-level perspective, you could从高层次的角度来看,你可以

  • force the four middle bits of Out off , prepare a mask from In as show in your question, and combine Out and mask via bitwise OR ( | )强制Out的四个中间位off ,从In准备一个掩码,如您的问题所示,并通过按位或( | )组合Out和掩码
  • force the four middle bits of Out off , prepare a mask from In as show in your question, and combine Out and mask via bitwise EXCLUSIVE OR ( ^ )强制关闭Out的四个中间位,从In准备一个掩码,如您的问题所示,并通过按位 EXCLUSIVE OR ( ^ ) 组合Out和掩码
  • force the four middle bits of Out on , prepare a mask from In similarly to how you do now, but with the outer bits on, and combine Out and mask via bitwise AND ( & )强制将Out的四个中间位打开,从In准备一个掩码,类似于你现在所做的,但要打开外位,并通过按位 AND ( & ) 组合Out和掩码
  • use a series of shifts, masks, and addition or bitwise OR operations to build up the wanted result section by section使用一系列移位、掩码和加法或按位或运算来逐段构建所需的结果

Forcing bits off is achieved by bitwise AND with a mask that has 0s at (only) the positions you want to turn off.强制位关闭是通过按位与实现的,掩码在(仅)您要关闭的位置处为 0。

Forcing bits on is achieved by bitwise OR with a mask that has 1s at (only) the positions you want to turn on.强制位打开是通过按位或与掩码实现的,该掩码(仅)在您要打开的位置处具有 1。

You already seem to have a handle on shifting, though you do need to be careful there if you happen to be shifting objects of signed types.您似乎已经掌握了转移的技巧,但如果您碰巧转移了有符号类型的对象,则确实需要小心。 Prefer to use unsigned types for bit manipulation wherever possible.尽可能使用无符号类型进行位操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM