Showing posts with label swap. Show all posts
Showing posts with label swap. Show all posts

Monday, March 24, 2014

Swap odd and even bits in an integer

This updated information has been further expanded upon on my new website. You can find the updated details here: https://k5kc.com/cs/algorithms/swap-odd-and-even-bits-in-an-integer/.
Problem
Write a program to swap odd and even bits in an integer with as few instructions as possible (e.g., bit 0 and bit 1 are swapped, bit 2 and bit 3 are swapped, etc).

Input : An integer x
Output : An integer y, which odd and even bit swapped (with 0th bit being least significant bit)

Example
Input  1:  10 = 1010
Output 1:  5  = 0101

(0th bit and 1st bit have been swapped,also 2nd and 3rd bit have been swapped) 

Input  2:  14 = 1110
Output 2:  13 = 1101

Solution

Method 1 - Right shift even bits and left shift odd bits
If we take a closer look at the example, we can observe that we basically need to right shift (>>) all even bits by 1 so that they become odd bits, and left shift (<<) all odd bits by 1 so that they become even bits. The following solution is based on this observation. The solution assumes that input number is stored using 32 bits.
Let the input number be x
1) Get all even bits of x by doing bitwise and of x with 0xAAAAAAAA. The number 0xAAAAAAAA is a 32 bit number with all even bits set as 1 and all odd bits as 0.
2) Get all odd bits of x by doing bitwise and of x with 0x55555555. The number 0x55555555 is a 32 bit number with all odd bits set as 1 and all even bits as 0.
3) Right shift all even bits.
4) Left shift all odd bits.
5) Combine new even and odd bits and return.

Here is the c code
unsigned int swapBits(unsigned int x)
{
    // Get all even bits of x
    unsigned int even_bits = x & 0xAAAAAAAA; 
 
    // Get all odd bits of x
    unsigned int odd_bits  = x & 0×55555555; 
 
    even_bits >>= 1;  // Right shift even bits
    odd_bits <<= 1;   // Left shift odd bits
 
    return (even_bits | odd_bits); // Combine even and odd bits
}

Note that we have not used normal int, but unsigned it. Because bitwise operators will not work in expected way on signed integer, as we have to take care of additional rules about MSB. In simple words, when a signed integer is shifted right, the MSB isn't necessarily zero, it's copied from the old MSB value.

Here is code in java
public static int swapOddEvenBits(int x) {
    return (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
}

References  - 
geeksforgeeks
stackoverflow
tian runhe,

Thanks.

Saturday, December 5, 2009

To swap the two nibbles in a byte

#include 

unsigned char swap_nibbles(unsigned char c)
{
  unsigned char temp1, temp2;
  temp1 = c & 0x0F;
  temp2 = c & 0xF0;
  temp1=temp1 << 4;
  temp2=temp2 >> 4;

  return(temp2|temp1); //adding the bits
}

int main(void)
{
  char ch=0x34;
  printf("\nThe exchanged value is %x",swap_nibbles(ch));
  return 0;
}

Friday, November 27, 2009

Swapping 2 variables using macro

Problem

How to swap 2 variables using macro?

 Solution

 #define swap(type,a,b) type temp;temp=a;a=b;b=temp;

Now, think what happens if you pass in something like this

 swap(int,temp,a) //You have a variable called "temp" (which is quite possible).


This is how it gets replaced by the macro
int temp;
temp=temp;
temp=b;
b=temp;

Swap two number in place without temporary variables.

Problem

Write a function to swap two number in place without temporary variables.

Solution


Method1 - The XOR or Exclusive trick
In C this should work:
a ^= b ^= a ^= b;


to simplify :
a=a^b;
b=a^b;
a=a^b;

OR
a^=b;
b^=a;
a^=b;

Following are operations in XOR

  • 0^0=0
  • 0^1=1
  • 1^0=1
  • 1^1=0
Hence, we have:
  • a=a^b: 'a' will save all the bits that a differs from b: if the bit that 'a' and 'b' differ, it gets 1, otherwise 0.
  • b=a^b: 'b' will compare to the difference between a and b: for the bit that 'b' and 'a' differ, it means a have 1 at this position and the result of a^b will assign that bit to 1; for the bit that 'b' and 'a' agree, it means a have 0 at this position and the result of a^b will assign that bit to 0.
  • a=a^b:  same logic
Although the code above works fine for most of the cases, it tries to modify variable 'a' two times between sequence points, so the behavior is undefined. What this means is it wont work in all the cases. This will also not work for floating-point values. Also, think of a scenario where you have written your code like this

Now, if suppose, by mistake, your code passes the pointer to the same variable to this function. Guess what happens? Since Xor'ing an element with itself sets the variable to zero, this routine will end up setting the variable to zero (ideally it should have swapped the variable with itself). This scenario is quite possible in sorting algorithms which sometimes try to swap a variable with itself (maybe due to some small, but not so fatal coding error). One solution to this problem is to check if the numbers to be swapped are already equal to each other.

swap(int *a, int *b)
{
  if(*a!=*b)
  {
    *a ^= *b ^= *a ^= *b;
  }
}

Method 2 - Simple addition and subtraction

This method is also quite popular
 a=a+b;
 b=a-b;
 a=a-b;

OR
a =((a = a + b) - (b = a - b));
But, note that here also, if a and b are big and their addition is bigger than the size of an int, even this might end up giving you wrong results.