Skip to content

Commit 0846019

Browse files
committed
Day-26: More Bit manipulation problems
1 parent 9dd25bf commit 0846019

File tree

4 files changed

+235
-2
lines changed

4 files changed

+235
-2
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
This repository will contain random algorithm and data structure problems I resolve to solve at least one a day.
33

44
## Current Streak
5-
**25 days**
5+
**26 days**
66
## Longest streak
7-
25 days (August 17, 2015 - Sept 10, 2015)
7+
26 days (August 17, 2015 - Sept 11, 2015)
88

99
## Include Directiory
1010
Include directory and sub directories contain STL like header file implementation of various algorithms and data structures. Following header only implementation,
@@ -55,3 +55,6 @@ please let me know.
5555
- Determine the next power of 2 for a given number.
5656
- Using bit manipulation determine if a number is multiple of 3.
5757
- Determine endianess of the machine, print a number in reverse Endianess.
58+
- Find the parity of given number.
59+
- Implement fast multiplication of a number to 7 using bit manipulation.
60+
- Reverse bits of unsigned integer (two methods - Reversing bit by bit & divide and conquer)

bit_manipulation/find_parity.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Problem : Determine parity of a number.
3+
* Parity refers to whether number contains odd or even number of set bits
4+
* Approach: We loop till number becomes zero and invert parity while unsetting
5+
* right most set bit.
6+
*/
7+
8+
#include <iostream>
9+
10+
bool getparity( int num )
11+
{
12+
bool parity = false;
13+
while( num ) {
14+
parity = !parity;
15+
num = (num & (num - 1));
16+
}
17+
return parity;
18+
}
19+
20+
int main()
21+
{
22+
int num;
23+
std::cout << "Enter number:";
24+
std::cin >> num;
25+
std::cout << "Parity of num is "
26+
<< (getparity(num) ? "odd" : "even")
27+
<< std::endl;
28+
return 0;
29+
}

bit_manipulation/multiply_by_7.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Problem : Muliply a number by 7 by using bit manipulation.
3+
* Approach : left shift n by 3 --> 8n
4+
* Therefore 7n = 8n - n;
5+
*/
6+
#include <iostream>
7+
8+
int multiply_by_7( int number )
9+
{
10+
return ((number << 3) - number);
11+
}
12+
13+
int main()
14+
{
15+
std::cout << "Enter a number:";
16+
int num;
17+
std::cin >> num;
18+
std::cout << "7 x " << num << " = "
19+
<< multiply_by_7(num) << std::endl;
20+
return 0;
21+
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/**
2+
* Problem : Reverse bits of an unsigned integer
3+
*/
4+
5+
#include <iostream>
6+
#include <sstream>
7+
#include <cassert>
8+
#include <algorithm>
9+
10+
/**
11+
* swapBits - utility function to swap bits at position i and j in unsigned int x
12+
* l represents bit at position i
13+
* r represents bit at position j
14+
* if l and r are same nothing needs to be done.
15+
* if l and r are different i.e. (l ^ r == 1),
16+
* we toggle bits at position i and j, and return new x.
17+
*/
18+
unsigned int swapBits(unsigned int x, unsigned int i, unsigned int j)
19+
{
20+
unsigned int l = ((x >> i) & 1);
21+
unsigned int r = ((x >> j) & 1);
22+
if ( l ^ r )
23+
{
24+
x ^= ((1U << i) | (1U << j));
25+
}
26+
return x;
27+
}
28+
29+
/*
30+
reverseBits1 : we swap first bit with last,
31+
second with one before last and so on.
32+
*/
33+
34+
unsigned int reverseBits1(int n)
35+
{
36+
unsigned bitCount = sizeof(n) * 8;
37+
for( unsigned int i = 0; i < bitCount/2; ++i) {
38+
n = swapBits(n, i, bitCount-i-1);
39+
}
40+
return n;
41+
}
42+
43+
44+
/**
45+
* Now, approach 2, divide and conquer:
46+
*
47+
* 01101001
48+
* / \
49+
* 0110 1001
50+
* / \ / \
51+
* 01 10 10 01
52+
* /\ /\ /\ /\
53+
* 0 1 1 0 1 0 0 1
54+
*
55+
* Just like merge sort, swap at each level and you are done.
56+
* First swap all odd and even bits, and then consecutive pair of bits
57+
* and so on.
58+
* This below approach will work on assumption that unsigned int size is 4bytes
59+
* or 32 bits.
60+
* Lets say a is 10 = 00000000 00000000 00000000 00001010
61+
* Step 1: swap all odd and even positions.
62+
* a = (a & 0x55555555) << 1 | (a & 0xAAAAAAAA) >> 1
63+
* 0x55555555 = 01010101 01010101 01010101 01010101
64+
* a = 00000000 00000000 00000000 00001010
65+
* --------------------------------------------------- and
66+
* a & (0x5..) = 00000000 00000000 00000000 00000000
67+
* a & (0x5..) << 1 = 00000000 00000000 00000000 00000000
68+
*
69+
* 0xAAAAAAAA = 10101010 10101010 10101010 10101010
70+
* a = 00000000 00000000 00000000 00001010
71+
* ------------------------------------------------- and
72+
* a & (0xA..) = 00000000 00000000 00000000 00001010
73+
* a & (0xA..) >> 1 = 00000000 00000000 00000000 00000101
74+
*
75+
* (a & (0x5..)) << 1 | (x & (0xA..)) >> 1
76+
* = 00000000 00000000 00000000 00000101
77+
* a = 00000000 00000000 00000000 00000101
78+
*
79+
***********************************************************
80+
*
81+
* Step2 : swap two consecutive bits with next consecutive two bits.
82+
* a = ((a & 0x33333333) << 2) | ((a & 0xCCCCCCCC) >> 2)
83+
* 0x33333333 = 00110011 00110011 00110011 00110011
84+
* a = 00000000 00000000 00000000 00000101
85+
* ------------------------------------------------- and
86+
* a & (0x33..)= 00000000 00000000 00000000 00000001
87+
*
88+
* a & (0x33.) << 2 = 00000000 00000000 00000000 00000100
89+
*
90+
* 0xCCCCCCCC = 11001100 11001100 11001100 11001100
91+
* a = 00000000 00000000 00000000 00000101
92+
* ------------------------------------------------- and
93+
* a & (0xcc..)= 00000000 00000000 00000000 00000100
94+
* a & (0xcc..) >> 2 = 00000000 00000000 00000000 00000001
95+
* (a & (0x33..) << 2) | (a & (0xcc) >> 2 )
96+
* = 00000000 00000000 00000000 00000101
97+
* a = 00000000 00000000 00000000 00000101
98+
*
99+
* **********************************************************
100+
*
101+
* Step3 : Swap 4 consecutive bits with next 4
102+
* a = ((a & 0x0F0F0F0F) << 4) | ((a & 0xF0F0F0F0) >> 4);
103+
* 0x0F0F0F0F = 00001111 00001111 00001111 00001111
104+
* a = 00000000 00000000 00000000 00000101
105+
* ------------------------------------------------ and
106+
* a & (0x0F..)= 00000000 00000000 00000000 00000101
107+
* a & (0x0F..) << 4 = 00000000 00000000 00000000 01010000
108+
*
109+
* 0xF0F0F0F0 = 11110000 11110000 11110000 11110000
110+
* a = 00000000 00000000 00000000 00000101
111+
* ---------------------------------------------------
112+
* a & (0xF0..)= 00000000 00000000 00000000 00000000
113+
* a & (0xF0..) >> 4 = 00000000 00000000 00000000 00000000
114+
* therefore a = ((a & 0x0F0F0F0F) << 4) | ((a & 0xF0F0F0F0) >> 4)
115+
* a = 00000000 00000000 00000000 01010000
116+
*
117+
* ***********************************************************
118+
*
119+
* Step4 : Swap consecutive bytes with each other
120+
* a = ((a & 0x00FF00FF) << 8) | ((a & 0xFF00FF00) >> 8);
121+
* 0x00FF00FF = 00000000 11111111 00000000 11111111
122+
* 0xFF00FF00 = 11111111 00000000 11111111 00000000
123+
* Clearly same as above operations, our a will become
124+
* a = 00000000 00000000 01010000 00000000
125+
*
126+
* ************************************************************
127+
* step5 : Finally swap two consecutive bytes with next two i.e. swapping left
128+
* 16 bits with right
129+
*
130+
* a = ((a & 0x0000FFFF) << 16) | ((a & 0xFFFF0000) >> 16);
131+
* So we will end up with
132+
* a = 01010000 00000000 00000000 00000000
133+
* Clearly which is reverse of how we started
134+
*/
135+
136+
unsigned int reverseBits2( unsigned int num )
137+
{
138+
assert(sizeof(num) == 4); // this method will work only for 32 bits
139+
num = ((num & 0x55555555) << 1) | ((num & 0xAAAAAAAA) >> 1);
140+
num = ((num & 0x33333333) << 2) | ((num & 0xCCCCCCCC) >> 2);
141+
num = ((num & 0x0F0F0F0F) << 4) | ((num & 0xF0F0F0F0) >> 4);
142+
num = ((num & 0x00FF00FF) << 8) | ((num & 0xFF00FF00) >> 8);
143+
num = ((num & 0x0000FFFF) << 16) | ((num & 0xFFFF0000) >> 16);
144+
return num;
145+
}
146+
147+
std::string printBinary(unsigned int n)
148+
{
149+
std::stringstream ss;
150+
std::string bin;
151+
int count = 0;
152+
while(n)
153+
{
154+
ss << (n % 2);
155+
n /= 2;
156+
++count;
157+
}
158+
bin = ss.str();
159+
bin.append(32-count, '0');
160+
std::reverse(bin.begin(), bin.end());
161+
return bin;
162+
}
163+
164+
int main()
165+
{
166+
std::cout << "Enter an unsigned number:";
167+
unsigned int n;
168+
std::cin >> n;
169+
std::cout << "Binary representation of entered number : "
170+
<< printBinary(n) << std::endl;
171+
std::cout << "Reversing bits of entered number\n";
172+
n = reverseBits1(n);
173+
std::cout << "Binary representation of number when bits are reversed: "
174+
<< printBinary(n) << std::endl;
175+
std::cout << "Reversing bits again\n";
176+
n = reverseBits2(n);
177+
std::cout << "Binary representation of number when bits are reversed: "
178+
<< printBinary(n) << std::endl;
179+
return 0;
180+
}

0 commit comments

Comments
 (0)