I have number with binary representation 0000abcd
.
How convert it to 0a0b0c0d
with smallest number of operations?
How convert 0a0b0c0d
back to 0000abcd
?
I was searching for a solution here: http://graphics.stanford.edu/~seander/bithacks.html and other
Generally the problem a bit more than described.
Given first number a₁b₁c₁d₁a₂b₂c₂d₂
and second number a₃a₄b₃b₄c₃c₄d₃d₄
If (a₁
and a₂
= 0
) then clear both a₃
and a₄
, if (a₃
and a₄
= 0
) then clear both a₁
and a₂
, etc.
My solution:
a₁b₁c₁d₁a₂b₂c₂d₂
OR 0 0 0 0 a₁b₁c₁d₁ ( a₁b₁c₁d₁a₂b₂c₂d₂ >> 4)
----------------
0 0 0 0 a b c d
? (magic transformation)
? ? ? ? ? ? ? ?
----------------
0 a 0 b 0 c 0 d
OR a 0 b 0 c 0 d 0 (0 a 0 b 0 c 0 d << 1)
----------------
a a b b c c d d
AND a₃a₄b₃b₄c₃c₄d₃d₄
----------------
A₃A₄B₃B₄C₃C₄D₃D₄ (clear bits)
UPDATED: (thanks for @AShelly)
x = a₁b₁c₁d₁a₂b₂c₂d₂
x = (x | x >> 4) & 0x0F
x = (x | x << 2) & 0x33
x = (x | x << 1) & 0x55
x = (x | x << 1)
y = a₃a₄b₃b₄c₃c₄d₃d₄
y = (y | y >> 1) & 0x55
y = (y | y >> 1) & 0x33
y = (y | y >> 2) & 0x0F
y = (y | y << 4)
work for 32-bit with constants 0x0F0F0F0F
, 0x33333333
, 0x55555555
(and twice long for 64-bit).