This question already has answers here:
What does the vertical pipe ( | ) mean in C++?
(4 answers)
Closed 4 years ago.
Having the follow code -
enum FileOpenFlags {
flagREAD = 1, flagWRITE = 2,
flagCREATE = 4, flagEND = 8,
flagAPPEND = flagWRITE | flagEND,
};
cout << flagAPPEND << endl;
gives 10 . can you explain me what the | did ?
It did a bitwise or of the two values.
flagWRITE's (2) binary representation is 0010
flagEND's (8) binary representation is 1000
0010 OR 1000 gives you 1010 which equals 10
It's called Bitwise OR........
It's a bitwise "OR" operator. So the bit value of 2 and 8 respectively get OR'd bitwise.
So:
1000 (flagEND = 8)
OR 0010 (flagWRITE = 2)
-----------
= 1010 (flagAppend = 10)
Related
I am trying to understand the logic behind the following code which sums 2 integers using bit manipulation:
def sum(a, b):
while b != 0:
carry = a & b
a = a ^ b
b = carry << 1
return a
As an example I used: a = 11 and b = 7
11 in binary representation is 1011
7 in binary representation is 0111
Then I walked through the algorithm:
iter #1: a = 1011, b = 0111
carry = 0011 (3 decimal)
a = 1100 (12 decimal)
b = 0110 (6 decimal)
iter #2: a = 1100, b = 0110
carry = 0100 (4 decimal)
a = 1010 (10 decimal)
b = 1000 (8 decimal)
iter #3: a = 1010, b = 1000
carry = 1000 (8 decimal)
a = 00010 (2 decimal)
b = 10000 (16 decimal)
iter #4: a = 00010, b = 10000
carry = 00000 (0 decimal)
a = 10010 (18 decimal)
b = 00000 (0 decimal)
We Done (because b is now 0).
As we can see, in all iterations a+b is always 18 which is the right answer.
However I failed to understand what is actually happens here. The value of a is going down and down with each iteration until suddenly pops to 18 in the last iteration. Also, can we learn anything from the value of the carry during the process?
I would love to understand the intuition behind this.
Thanks to #WJS answer I think I got it.
let's add 11 and 7 as before, but let's do it in the following order:
First, calculate it without the carry.
Second, calculate only the carry.
Then add both parts.
01011
00111
-----
01100 (neglecting carry)
00110 (finding only the carry)
-----
10010 (sum)
Now, to find the first part, how can we get rid of the carry bits? with XOR.
To find the second part, we use AND and then shift it 1 bit left to place it "under" the right bit.
Now all we have to do is sum both parts. The whole point is not using + operator so how can we do that? Recursion!
We assign the first part to a and the second part to b and we repeat this process until b=0 which means we are done.
Perhaps if you take a simpler example it will help.
a = 11
b = 11
a & b == 11 since AND returns 1's where both bits in the same
position are 1. These are the carry bits.
Now get rid of the the carry locations using exclusive or
a = a ^ b == 00
But a `carry` would cause addition to add bits one position to
the left so shift the carry bits left by 1 bit.
b = carry << 1 = 110
now repeat the process
carry = a & b = 0 & 110 == 0 no more carries
b = carry << 1 == 0
done.
11 + 11 = 110 = 3 + 3 = 6
Understanding the roles of (AND) & and (XOR) ^ are key. Applying those to slightly more complex examples should help. But ignore the interim decimal values as they don't help much. Think only about what is happening in binary.
I think this is easy to understand if you look at what happens with individual bits.
First step is calculating carry which only happens in binary when both bits are 1, so a&b calculates that for every bit. Then bitwise addition is happening via XOR (ignoring carry), and XOR works because:
0+0=0 (==0^0)
1+0=1 (==1^0)
1+1=0 (==1^1, generates carry bit which we ignore)
Next step is to shift carry to the left (<<1), move it to b and repeat until carry is empty.
This question already has answers here:
What does the statement if (counter & (1<<j)) mean and how does it work?
(2 answers)
Closed last year.
I have an array, A=[1,2,3,4] (where n=4). I want to generate sub-sequences from this array.
Number of subsequences is (2^n -1)
Run from counter 0001 to 1111
for (int counter = 1; counter < 2^n; counter++)
{
for (int j = 0; j < n; j++)
{
Check if the jth bit in the counter is set. If set then print jth element from arr[]
if (counter & (1<<j))
cout << arr[j] << " ";
}
cout << endl;
}
}
can anyone explain me? How it works " counter & (1<
The logic goes like this. Say, like you put in the example, you have n = 4, and, to avoid confusion, let's say the array is A = [5, 7, 8, 9], for example. Then you want all the possible sequences containing some elements (at least one) from the original array. So you want a sequence containing only the first one, a sequence containing the first and the second, the first and the third, etc. Each printed sequence may or may not contain each of the elements in the array. So you could see it as something like this:
| 5 | 7 | 8 | 9 | Sequence
----------------- --------
| 1 | 0 | 0 | 0 | -> 5
| 1 | 1 | 0 | 0 | -> 5 7
| 1 | 0 | 1 | 0 | -> 5 8
...
That is, each sequence can be expressed as a list of bits, each indicating whether each member of the array is included.
In this loop:
for (int counter = 1; counter < 2^n; counter++)
The program iterates from 1 to 2^n - 1, that is 15 in this case. So the values that you get for counter are:
Dec Binary
--- ------
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
If you look closely, you will see that we have all the possible sequences of four elements composed of 0 and 1 in binary (except 0000, which would be the empty sequence and does not interest us). In this loop:
for (int j = 0; j < n; j++)
The program just goes through each bit of counter, from 0 (the rightmost) to n - 1 and whenever it finds a 1 it outputs the corresponding array element. The condition:
if (counter & (1<<j))
Simply computes the number 1<<j which is 1 plus j number of zeros at its right (so, for example, for j = 0 it would be 1 and for j = 2 it would be 100) and then a bitwise and operation, so it basically "filters" the j-th bit only (e.g. 1101 & 100 = 0100), and if the result is not zero then it means there was a one, and so arr[j] must be printed.
Obviously, the problem with the function is that it is limited to the number of bits that the variable counter can hold. That depends on its declared type and your architecture/compiler, but typically it will be either 32 or 64.
This question already has answers here:
Confusing operator precedence: a << b + c << d
(4 answers)
Closed 8 years ago.
when am I applying left shifting to 1 by 4 bit as 1<<4 it printing 16 as the value but if I will apply shifting like 1<<4 + 1<<3 then it printing 256 as a result,
I am not getting, how many shifting is apply and how it is working?
but according to me answer should be 24 by applying 4 left shift + 3 shift
1 << 4 + 1 << 3
Is actually interpreted as
(1 << ( 4 + 1 )) << 3
See?
1 << 5 --> 32
32 << 3 --> 256
When in doubt, use more parentheses!
(1 << 5) + (1 << 3) --> 24
This question already has answers here:
A sign in C++ I've never seen before: |=
(5 answers)
Closed 9 years ago.
I am trying to understand |= in c++, I have sample code
int x = 0 ;
x |= 3;
std::cout<<x <<std::endl;
x |= 6;
std::cout<<x <<std::endl;
output is :
3
7
how is this possible, is it related to bit addition??
It is a bitwise or and assignment. It is the same as x = x | 3.
In binary bitwise or is equivalent to "if it's a 1 in either number it will be a 1 in the result". So x |= 3 makes 3. Then x is 11 in binary and 6 is 110 in binary so 11 | 101 = 111 (binary) = 7 (decimal).
x |= 3
means
x = x |3
bitwise or operation.
Its a bitwise OR.
First case:
0011(3 in decimal)
0000(0 in decimal)
So, the OR of both is:
0011 OR 0000 = 0011
= 2^0 + 2^1
= 3
For second case, the OR works as follows:
0011 (3 in decimal)
0110 (6 in decimal)
Output of OR is 0111 which in decimal is:
0011 OR 0110 = 0111
= 2^0 + 2^1 + 2^2
= 1+2+4
= 7
It is bitwise
OR
and then assignment. This means the same as x = x | 3.
about bitwise OR
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
why is initializing an integer in VC++ to 010 different from initialising it to 10?
This got me very confused, and I hope one of you can answer my question. How come this code will produce the output "116"?
#include <iostream>
int main()
{
std::cout << 0164 << std::endl;
return 0;
}
The code has been compiled with MSVC++ 2010 and g++ under Mac OS X.
"cout" can print '0' alone and '164' alone, but as soon '0' is the first digit in the number the output changes.
Because the 0 in front makes the number be interpreted as octal.
0164 =
4 * 1 +
6 * 8 +
1 * 64
= 116
Or, via binary:
0164 =
0 1 6 4 =
000 001 110 100 =
1110100 =
116
The same goes for hexadecimal numbers, you write them as 0x1FA for example.
In C and its brethren, a number with 0 on the front is octal, not decimal.
Hence your number is 1 * 82 (1 * 64 = 64) plus 6 * 81 (6 * 8 = 48) plus 4 * 80 (4 * 1 = 4) which equates to 116.
See here for a large treatise on what hexadecimal and octal are in C.