Skip to content

Commit

Permalink
Day-26: More Bit manipulation problems
Browse files Browse the repository at this point in the history
  • Loading branch information
mandliya committed Sep 11, 2015
1 parent 9dd25bf commit 0846019
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 2 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
This repository will contain random algorithm and data structure problems I resolve to solve at least one a day.

## Current Streak
**25 days**
**26 days**
## Longest streak
25 days (August 17, 2015 - Sept 10, 2015)
26 days (August 17, 2015 - Sept 11, 2015)

## Include Directiory
Include directory and sub directories contain STL like header file implementation of various algorithms and data structures. Following header only implementation,
Expand Down Expand Up @@ -55,3 +55,6 @@ please let me know.
- Determine the next power of 2 for a given number.
- Using bit manipulation determine if a number is multiple of 3.
- Determine endianess of the machine, print a number in reverse Endianess.
- Find the parity of given number.
- Implement fast multiplication of a number to 7 using bit manipulation.
- Reverse bits of unsigned integer (two methods - Reversing bit by bit & divide and conquer)
29 changes: 29 additions & 0 deletions bit_manipulation/find_parity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Problem : Determine parity of a number.
* Parity refers to whether number contains odd or even number of set bits
* Approach: We loop till number becomes zero and invert parity while unsetting
* right most set bit.
*/

#include <iostream>

bool getparity( int num )
{
bool parity = false;
while( num ) {
parity = !parity;
num = (num & (num - 1));
}
return parity;
}

int main()
{
int num;
std::cout << "Enter number:";
std::cin >> num;
std::cout << "Parity of num is "
<< (getparity(num) ? "odd" : "even")
<< std::endl;
return 0;
}
21 changes: 21 additions & 0 deletions bit_manipulation/multiply_by_7.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Problem : Muliply a number by 7 by using bit manipulation.
* Approach : left shift n by 3 --> 8n
* Therefore 7n = 8n - n;
*/
#include <iostream>

int multiply_by_7( int number )
{
return ((number << 3) - number);
}

int main()
{
std::cout << "Enter a number:";
int num;
std::cin >> num;
std::cout << "7 x " << num << " = "
<< multiply_by_7(num) << std::endl;
return 0;
}
180 changes: 180 additions & 0 deletions bit_manipulation/reverseBitsOfAnInteger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/**
* Problem : Reverse bits of an unsigned integer
*/

#include <iostream>
#include <sstream>
#include <cassert>
#include <algorithm>

/**
* swapBits - utility function to swap bits at position i and j in unsigned int x
* l represents bit at position i
* r represents bit at position j
* if l and r are same nothing needs to be done.
* if l and r are different i.e. (l ^ r == 1),
* we toggle bits at position i and j, and return new x.
*/
unsigned int swapBits(unsigned int x, unsigned int i, unsigned int j)
{
unsigned int l = ((x >> i) & 1);
unsigned int r = ((x >> j) & 1);
if ( l ^ r )
{
x ^= ((1U << i) | (1U << j));
}
return x;
}

/*
reverseBits1 : we swap first bit with last,
second with one before last and so on.
*/

unsigned int reverseBits1(int n)
{
unsigned bitCount = sizeof(n) * 8;
for( unsigned int i = 0; i < bitCount/2; ++i) {
n = swapBits(n, i, bitCount-i-1);
}
return n;
}


/**
* Now, approach 2, divide and conquer:
*
* 01101001
* / \
* 0110 1001
* / \ / \
* 01 10 10 01
* /\ /\ /\ /\
* 0 1 1 0 1 0 0 1
*
* Just like merge sort, swap at each level and you are done.
* First swap all odd and even bits, and then consecutive pair of bits
* and so on.
* This below approach will work on assumption that unsigned int size is 4bytes
* or 32 bits.
* Lets say a is 10 = 00000000 00000000 00000000 00001010
* Step 1: swap all odd and even positions.
* a = (a & 0x55555555) << 1 | (a & 0xAAAAAAAA) >> 1
* 0x55555555 = 01010101 01010101 01010101 01010101
* a = 00000000 00000000 00000000 00001010
* --------------------------------------------------- and
* a & (0x5..) = 00000000 00000000 00000000 00000000
* a & (0x5..) << 1 = 00000000 00000000 00000000 00000000
*
* 0xAAAAAAAA = 10101010 10101010 10101010 10101010
* a = 00000000 00000000 00000000 00001010
* ------------------------------------------------- and
* a & (0xA..) = 00000000 00000000 00000000 00001010
* a & (0xA..) >> 1 = 00000000 00000000 00000000 00000101
*
* (a & (0x5..)) << 1 | (x & (0xA..)) >> 1
* = 00000000 00000000 00000000 00000101
* a = 00000000 00000000 00000000 00000101
*
***********************************************************
*
* Step2 : swap two consecutive bits with next consecutive two bits.
* a = ((a & 0x33333333) << 2) | ((a & 0xCCCCCCCC) >> 2)
* 0x33333333 = 00110011 00110011 00110011 00110011
* a = 00000000 00000000 00000000 00000101
* ------------------------------------------------- and
* a & (0x33..)= 00000000 00000000 00000000 00000001
*
* a & (0x33.) << 2 = 00000000 00000000 00000000 00000100
*
* 0xCCCCCCCC = 11001100 11001100 11001100 11001100
* a = 00000000 00000000 00000000 00000101
* ------------------------------------------------- and
* a & (0xcc..)= 00000000 00000000 00000000 00000100
* a & (0xcc..) >> 2 = 00000000 00000000 00000000 00000001
* (a & (0x33..) << 2) | (a & (0xcc) >> 2 )
* = 00000000 00000000 00000000 00000101
* a = 00000000 00000000 00000000 00000101
*
* **********************************************************
*
* Step3 : Swap 4 consecutive bits with next 4
* a = ((a & 0x0F0F0F0F) << 4) | ((a & 0xF0F0F0F0) >> 4);
* 0x0F0F0F0F = 00001111 00001111 00001111 00001111
* a = 00000000 00000000 00000000 00000101
* ------------------------------------------------ and
* a & (0x0F..)= 00000000 00000000 00000000 00000101
* a & (0x0F..) << 4 = 00000000 00000000 00000000 01010000
*
* 0xF0F0F0F0 = 11110000 11110000 11110000 11110000
* a = 00000000 00000000 00000000 00000101
* ---------------------------------------------------
* a & (0xF0..)= 00000000 00000000 00000000 00000000
* a & (0xF0..) >> 4 = 00000000 00000000 00000000 00000000
* therefore a = ((a & 0x0F0F0F0F) << 4) | ((a & 0xF0F0F0F0) >> 4)
* a = 00000000 00000000 00000000 01010000
*
* ***********************************************************
*
* Step4 : Swap consecutive bytes with each other
* a = ((a & 0x00FF00FF) << 8) | ((a & 0xFF00FF00) >> 8);
* 0x00FF00FF = 00000000 11111111 00000000 11111111
* 0xFF00FF00 = 11111111 00000000 11111111 00000000
* Clearly same as above operations, our a will become
* a = 00000000 00000000 01010000 00000000
*
* ************************************************************
* step5 : Finally swap two consecutive bytes with next two i.e. swapping left
* 16 bits with right
*
* a = ((a & 0x0000FFFF) << 16) | ((a & 0xFFFF0000) >> 16);
* So we will end up with
* a = 01010000 00000000 00000000 00000000
* Clearly which is reverse of how we started
*/

unsigned int reverseBits2( unsigned int num )
{
assert(sizeof(num) == 4); // this method will work only for 32 bits
num = ((num & 0x55555555) << 1) | ((num & 0xAAAAAAAA) >> 1);
num = ((num & 0x33333333) << 2) | ((num & 0xCCCCCCCC) >> 2);
num = ((num & 0x0F0F0F0F) << 4) | ((num & 0xF0F0F0F0) >> 4);
num = ((num & 0x00FF00FF) << 8) | ((num & 0xFF00FF00) >> 8);
num = ((num & 0x0000FFFF) << 16) | ((num & 0xFFFF0000) >> 16);
return num;
}

std::string printBinary(unsigned int n)
{
std::stringstream ss;
std::string bin;
int count = 0;
while(n)
{
ss << (n % 2);
n /= 2;
++count;
}
bin = ss.str();
bin.append(32-count, '0');
std::reverse(bin.begin(), bin.end());
return bin;
}

int main()
{
std::cout << "Enter an unsigned number:";
unsigned int n;
std::cin >> n;
std::cout << "Binary representation of entered number : "
<< printBinary(n) << std::endl;
std::cout << "Reversing bits of entered number\n";
n = reverseBits1(n);
std::cout << "Binary representation of number when bits are reversed: "
<< printBinary(n) << std::endl;
std::cout << "Reversing bits again\n";
n = reverseBits2(n);
std::cout << "Binary representation of number when bits are reversed: "
<< printBinary(n) << std::endl;
return 0;
}

0 comments on commit 0846019

Please sign in to comment.