for (unsigned int i = 1; i <= 100; i++) {
if (i & 0x00000001) {
std::cout << i<<",";
}
}
why does (and how): if( i & 0x00000001 )
figure out the odd number?
for (unsigned int i = 1; i <= 100; i++) {
if (i & 0x00000001) {
std::cout << i<<",";
}
}
why does (and how): if( i & 0x00000001 )
figure out the odd number?
It's using a bitwise "and" operator to mask off all but the last bit. If the last bit is a 1, the number is odd. Is that enough explanation?
When we look at numbers in base 10, it's easy to tell if a number is divisible by 10: it has a 0 in the last position. The code above looks at the digit in the last position as well, but in base 2. If it's non-zero, the number is not divisible by 2.
It masks off the last bit. If you look at each place in the binary representation of a number (..., 256, 128, 64, 32, 16, 8, 4, 2, and 1), you'll notice that only the one's place is odd. All the rest of the places have an even value whether the bits are set or cleared (zero being even). And adding even numbers will always give an even number. Only that last one's place determines the parity of the number. The i & &0x00000001
part just isolates that last one's place.
You are doing bitwise comparison. The if bit0 AND bit0 are both 1, then the answer's bit0 = 1.
Seeing that &0x00000001 is 1, any numbers with this bit are odd.
0x00000001 = 1
0x00000010 = 2
0x00000011 = 3
etc.
So, if you do a bitwise AND
00000001 AND
00000001 =
00000001 (same as true)
00000010 AND
00000001 =
00000000 (same as false)
00000011 AND
00000001 =
00000001 (same as true)
etc
0x00000001
is 1
in binary, although it's written in hexadecimal (base-16) notation. That's the 0x
part.
&
is the bit-wise 'AND' operator, which is used to do binary digit (bit) manipulations.
i & 1
converts all of the binary digits of i to zero, except for the last one.
It's straightforward to convert the resulting 1-bit number to a boolean, for evaluation by the if
statement.
The following chart shows the last 16 binary digits of i, and what happens to them.
i: i in binary: i & 1 in binary: convert to boolean
---- ------------------- ------------------- ---------------------
1 0000000000000001 0000000000000001 true
2 0000000000000010 0000000000000000 false
3 0000000000000011 0000000000000001 true
4 0000000000000100 0000000000000000 false
5 0000000000000101 0000000000000001 true
6 0000000000000110 0000000000000000 false
7 0000000000000111 0000000000000001 true
8 0000000000001000 0000000000000000 false
... ... ... ...
99 0000000001100011 0000000000000001 true
100 0000000001100100 0000000000000000 false
Odd numbers are all numbers of the form (2*n+1) where n is any integer (-2,-1,0,1....). So to find an odd number you have to see if the integer you're working with has that '+1' on it. When stored as an unsigned integer, a number can be expressed as the sum of powers of 2: 2^0 + 2^1 +2^2 + 2^4, etc. The binary version of the unsigned integer looks like a truth map of sorts: for every place there's a '1' in the binary number, add that power of two to the number. So, if you start at the right most digit in the binary representation of the unsigned integer and move left, each digit represents a power of two. If the digit is 1 then you add that power of two to the running sum and when you reach the end of the binary number.
Thus: 10001110b can be converted into an integer by summing the powers of two:
Rightmost: 2^1 + 2^2 + 2^3 + 2^7 :Leftmost = 141
The trick is that the rightmost digit represents 2^0. This is always 1. All the other digits represent even numbers. So, in terms of odd numbers you have to find the '+1'. That corresponds to the rightmost digit. All the other digits represent numbers of the form '2*n'. Therefore, to determine if a number of this format (unsigned integer) is odd you need only see if the right most bit is '1'.
The operation performed on the unsigned integer is a logical AND operation. Anything AND'd with 0 is 0, and 1 AND'd with 1 is 1. So the operation will cause all binary digits in the unsigned integer representation to be 0 except for the binary digit representing 2^0 (which is 1). So the unsigned integer binary representation will boil down to 0x00000001 if it's odd and 0x00000000 if it's even.
Note: When I write 0x00000000, the '0x' means that it's hexadecimal format. Each '0' represents four bits. So 0x00 is hexadecimal for 00000000b Written out in binary, the resulting possible unsigned integer binary representations after AND'ing the unsigned integer are:
00000000000000000000000000000000b == 0 and 00000000000000000000000000000001b == 1
Before I say the following, I'll first say that I pretty much always use the bit test to determine whether an int is odd or even.
But, strictly speaking, you should use (i % 2)
or ((i % 2) != 0)
to determine is i
is odd. This will work regardless of the represenation of negative numbers, while on a one's complement machine (-3 & 0x01) will return zero (a false result) even though clearly it's odd.
I realize that machiens that use something other than two's complement to represent negative number are very,very rare nowadays, but it's also true that compilers nowadays will universally compile (i % 2)
to a bit test anyway. And remember, I usually don't follow my own advice here, so that's might be an indication of the true value of this suggestion.
The bitwise AND operator follows this truth table for every bit:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
Since computers work with numbers in base 2 and each bit represents a power of two value (1,2,4,8,16 ..),
the least significant bit represents the only odd number, regardless how big or small the value is, and regardless whether it is signed or unsigned. Since the resulting bit is only set if both operands have that bit set, the result is true if and only if the number is odd.
Example:
0b11101011 =
(1 * 2^0) + (1 * 2^1) + (0 * 2^2) + (1 * 2^3) +
(0 * 2^4) + (1 * 2^5) + (1 * 2^6) + (1 * 2^7) =
1 + 2 + 0 + 8 + 0 + 32 + 64 + 128 = 235
Without the least significant bit set, the value would be 234 and hence an even number.
For Example how we make a Binary Equivalent
8 4 2 1
0 0 0 0 = 0
0 0 0 1 = 1
0 0 1 0 = 2
0 0 1 1 = 3
So you can see for any odd no. LSB is always set , Same you check :)
I hope my answer is clear