views:

80

answers:

5

I have an arbitrary 8-bit binary number e.g., 11101101

I have to swap all the pair of bits like:

Before swapping: 11-10-11-01 After swapping: 11-01-11-10

I was asked this in an interview !

A: 

b = (a & 170 >> 1) | (a & 85 << 1)

Andy
This is completely unreadable; also, it's inefficient and even incorrect for edge cases. Dividing by two is not equivalent to a one-bit right shift for negative numbers.
tdammers
same as tdammers answer but that is cleaner and explicitly binary, while you use decimal numbers.
vulkanino
-1 very unreadable
Tomas
A: 

I would first code it 'longhand' - that is to say in several obvious, explicit stages, and use that to validate that the unit tests I had in place were functioning correctly, and then only move to more esoteric bit manipulation solutions if I had a need for performance (and that extra performance was delivered by said improvments)

Code for people first, computers second.

Visage
-1 that does not answer the question at all
Tomas
+7  A: 

In pseudo-code:

x = ((x & 0b10101010) >> 1) | ((x & 0b01010101) << 1)

It works by handling the low bits and high bits of each bit-pair separately and then combining the result:

  • The expression x & 0b10101010 extracts the high bit from each pair, and then >> 1 shifts it to the low bit position.
  • Similarly the expression (x & 0b01010101) << 1 extracts the low bit from each pair and shifts it to the high bit position.
  • The two parts are then combined using bitwise-OR.

Since not all languages allow you to write binary literals directly, you could write them in for example hexadecimal:

Binary        Hexadecimal  Decimal 
0b10101010    0xaa         170
0b01010101    0x55         85
Mark Byers
Given that not all languages respect the pattern 0b..., it's probably worth noting that it is 0xAA and 0x55 in hex respectively.
userx
@userx: +1 Yes, that is definitely worth noting. Added.
Mark Byers
Thanks Mark. Thats awesome method !
RaviPathak
+3  A: 
  1. Make two bit masks, one containing all the even bits and one containing the uneven bits (10101010 and 01010101).
  2. Use bitwise-and to filter the input into two numbers, one having all the even bits zeroed, the other having all the uneven bits zeroed.
  3. Shift the number that contains only even bits one bit to the left, and the other one one bit to the right
  4. Use bitwise-or to combine them back together.

Example for 16 bits (not actual code):

short swap_bit_pair(short i) {
    return ((i & 0101010110101010b) >> 1) | ((i & 0x0101010101010101b) << 1));
}
tdammers
Um.. I think you mean 0xAA instead of 0x10101010 (0xAA being 10101010 in binary) and 0x55 instead of 0x01010101. Well for a byte anyways. 0xAAAA and 0x5555 respectively for a short.
userx
Yeah, already edited the C-like pseudocode to use binary instead. The original question states 8 bits anyway, so...
tdammers
A: 

b = n xor (n shr 4)

where xor is exclusive or and shr is circular-rotate for 8-bits

Lie Ryan