Reputation: 1281
I'm trying to change the 4 middle bits of a byte to correspond to the High nibble of another byte:
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.
How can I do this?
Note: The 'X' represents any bit, 0 or 1, just to distinguish what came from the input.
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
?
Upvotes: 4
Views: 1311
Reputation:
simple:
out &= 0b11000011;
out |= (in >> 2 & 0b00111100);
out &= 0b11000011
sets out
to 0bxx0000xx
preserving 2 most significant bits and 2 least significant bits. in >> 2
shifts input by 2 giving us 0xYYABCDEF
, YY
could be 00
or 11
depending on what A
is. To get rid of YY
and EF
we do & 0b00111100
.
As pointed by @JB 0B
is not standard notation, thus you should use something else, most preferably hex 0x
notation. 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`
Upvotes: 7
Reputation: 181724
There are multiple alternatives. From a high-level perspective, you could
Out
off, prepare a mask from In
as show in your question, and combine Out
and mask via bitwise OR (|
)Out
off, prepare a mask from In
as show in your question, and combine Out
and mask via bitwise EXCLUSIVE OR (^
)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 (&
)Forcing bits off is achieved by bitwise AND with a mask that has 0s at (only) the positions you want to turn off.
Forcing bits on is achieved by bitwise OR with a mask that has 1s at (only) the positions you want to turn on.
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.
Upvotes: 1
Reputation: 26194
Assuming in
and out
are unsigned char
, and that CHAR_BIT == 8
:
out = (out & 0xC3) | ((in >> 2) & 0x3C);
i.e. 4 operations in total.
Upvotes: 4