Programare Bit Operations
Programare Bit Operations
Output:
a = 5, b = 9
a&b = 1
a|b = 13
a^b = 12
~a = 250
b<<1 = 18
b>>1 = 4
Interesting facts about bitwise operators
The left shift and right shift operators should not be used for negative
numbers. If any of the operands is a negative number, it results in undefined
behaviour. For example results of both -1 << 1 and 1 << -1 is undefined.
Also, if the number is shifted more than the size of integer, the behaviour is
undefined. For example, 1 << 33 is undefined if integers are stored using 32
bits. See this for more details.
1.The bitwise XOR operator is the most useful operator from technical
interview perspective. It is used in many problems. A simple example
could be “Given a set of numbers where all elements occur even number
of times except one number, find the odd occurring number” This problem
can be efficiently solved by just doing XOR of all numbers.
#include <stdio.h>
// Function to return the only odd
// occurring element
int findOdd(int arr[], int n)
{
int res = 0, i;
for (i = 0; i < n; i++)
res ^= arr[i];
return res;
}
// Driver Method
int main(void)
{
int arr[] = { 12, 12, 14, 90, 14, 14, 14 };
int n = sizeof(arr) / sizeof(arr[0]);
printf("The odd occurring element is %d ",
findOdd(arr, n));
return 0;
}
Output:
The odd occurring element is 90
The following are many other interesting problems using XOR operator.
Output:
False True
Output:
x << 1 = 38
x >> 1 = 9
Output:
Odd
Output:
Signed Result -2
Important Links:
1.Bits manipulation (Important tactics)
2.Bitwise Hacks for Competitive Programming
3.Bit Tricks for Competitive Programming
Output:
6
We have passed the parameter by ‘call by reference’ to make permanent
changes in the number.
2. How to unset/clear a bit at n’th position in the number ‘num’ :
Suppose we want to unset a bit at nth position in number ‘num’ then we
have to do this with the help of ‘AND’ (&) operator.
•First we left shift ‘1’ to n position via (1<<n) than we use bitwise NOT
operator ‘~’ to unset this shifted ‘1’.
•Now after clearing this left shifted ‘1’ i.e making it to ‘0’ we will ‘AND'(&)
with the number ‘num’ that will unset bit at nth position position.
#include <iostream>
using namespace std;
// First step is to get a number that has all 1's except the given
position.
void unset(int &num,int pos)
{
//Second step is to bitwise and this number with given number
num &= (~(1 << pos));
}
int main()
{
int num = 7;
int pos = 1;
unset(num, pos);
cout << num << endl;
return 0;
}
Output:
5
3. Toggling a bit at nth position :
Toggling means to turn bit ‘on'(1) if it was ‘off'(0) and to turn ‘off'(0) if it was
‘on'(1) previously.We will be using ‘XOR’ operator here which is this ‘^’. The
reason behind ‘XOR’ operator is because of its properties.
•Properties of ‘XOR’ operator.
•1^1 = 0
•0^0 = 0
•1^0 = 1
•0^1 = 1
•If two bits are different then ‘XOR’ operator returns a set bit(1) else it
returns an unset bit(0).
#include <iostream>
using namespace std;
// First step is to shift 1,Second step is to XOR with given number
void toggle(int &num,int pos)
{
num ^= (1 << pos);
}
int main()
{
int num = 4;
int pos = 1;
toggle(num, pos);
cout << num << endl;
return 0;
}
Output:
6
4. Checking if bit at nth position is set or unset:
It is quite easily doable using ‘AND’ operator.
Left shift ‘1’ to given position and then ‘AND'(‘&’).
#include <iostream>
using namespace std;
bool at_position(int num,int pos)
{
bool bit = num & (1<<pos);
return bit;
}
int main()
{
int num = 5;
int pos = 0;
bool bit = at_position(num, pos);
cout << bit << endl;
return 0;
}
Output:
1
Observe that we have first left shifted ‘1’ and then used ‘AND’ operator to
get bit at that position. So if there is ‘1’ at position ‘pos’ in ‘num’, then after
‘AND’ our variable ‘bit’ will store ‘1’ else if there is ‘0’ at position ‘pos’ in the
number ‘num’ than after ‘AND’ our variable bit will store ‘0’.
Some more quick hacks:
•Inverting every bit of a number/1’s complement:
If we want to invert every bit of a number i.e change bit ‘0’ to ‘1’ and bit
‘1’ to ‘0’.We can do this with the help of ‘~’ operator. For example : if
number is num=00101100 (binary representation) so ‘~num’ will be
‘11010011’.
Output:
-5
• Two’s complement of the number: 2’s complement of a number is 1’s
complement + 1.
So formally we can have 2’s complement by finding 1s complement and
adding 1 to the result i.e (~num+1) or what else we can do is using ‘-‘
operator.
#include <iostream>
using namespace std;
int main()
{
int num = 4;
int twos_complement = -num;
cout << "This is two's complement " << twos_complement << endl;
cout << "This is also two's complement " << (~num+1) << endl;
return 0;
}
Output:
This is two's complement -4
This is also two's complement -4
•Stripping off the lowest set bit :
In many situations we want to strip off the lowest set bit for example in
Binary Indexed tree data structure, counting number of set bit in a number.
We do something like this:
X = X & (X-1)
But how does it even work ?
Let us see this by taking an example, let X = 1100.
(X-1) inverts all the bits till it encounter lowest set ‘1’ and it also invert that
lowest set ‘1’.
X-1 becomes 1011. After ‘ANDing’ X with X-1 we get lowest set bit stripped.
#include <iostream>
using namespace std;
void strip_last_set_bit(int &num)
{
num = num & (num-1);
}
int main()
{
int num = 7;
strip_last_set_bit(num);
cout << num << endl;
return 0;
}
Output:
6
•Getting lowest set bit of a number:
This is done by using expression ‘X &(-X)’Let us see this by taking an
example:Let X = 00101100. So ~X(1’s complement) will be ‘11010011’ and
2’s complement will be (~X+1 or -X) i.e ‘11010100’.So if we ‘AND’ original
number ‘X’ with its two’s complement which is ‘-X’, we get lowest set bit.
00101100
& 11010100
-----------
00000100
#include <iostream>
using namespace std;
int lowest_set_bit(int num)
{
int ret = num & (-num);
return ret;
}
int main()
{
int num = 10;
Output:
2
Bit Tricks for Competitive Programming
Refer BitWise Operators Articles for more articles on Bit Hacks.
Logic: All the power of 2 have only single bit set e.g. 16 (00010000). If we
minus 1 from this, all the bits from LSB to set bit get toggled, i.e., 16-1 = 15
(00001111). Now if we AND x with (x-1) and the result is 0 then we can say
that x is power of 2 otherwise not. We have to take extra care when x = 0.
Example
x = 16(000100000)
x – 1 = 15(00001111)
x & (x-1) = 0
so 16 is power of 2
Input: 6
Output: 7
Output: 3
b ^= a;
a ^= b;
Example :
Number = 23,