Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitwise replacing bits in two numbers

Tags:

I'm interested how I can swap interval of bits from number X to number Y using bitwise operations.

So for example I have number:

X = 00000000 Y = 00111111

positionStart, positionEnd

And I want to replace [positionStart, positionEnd] bits in X with bits from Y at the same position.

like image 425
StupidFox Avatar asked Feb 23 '18 13:02

StupidFox


2 Answers

If you have a mask m that indicates the bits that you want to move or swap, you could move them like this:

x = x ^ ((x ^ y) & m)

Or swap them like this:

t = (x ^ y) & m
x ^= t
y ^= t

This could be explained as taking the bitwise difference between x and y, only in places where m is set. Then XORing x with that flips the bits in x where x and y are different (and m is set) so it changes those bits of x into bits of y. The same thing applies to y.


A mask might be created like

m = (2 << end) - (1 << start)
like image 171
harold Avatar answered Sep 22 '22 13:09

harold


First make a mask (this assumes Python-like indexing from least to most significant, zero-based and not including the upper index):

M = (1 << positionEnd) - 1) & ~((1 << positionStart) - 1)

If you want to replace the bits in X with those in Y:

X = (X & ~M) | (Y & M)

If you want to swap, you can use a third variable or can do something like a masked XOR trick:

X = (X & ~M) | ((X ^ Y) & M)
Y = (Y & ~M) | ((X ^ Y) & M)
X = (X & ~M) | ((X ^ Y) & M)
like image 36
jdehesa Avatar answered Sep 22 '22 13:09

jdehesa