forked from mandliya/algorithms_and_data_structures
-
Notifications
You must be signed in to change notification settings - Fork 1
/
reverseBitsOfAnInteger.cpp
180 lines (171 loc) · 5.88 KB
/
reverseBitsOfAnInteger.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
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;
}