Reputation: 31
void DecInBinary(unsigned int dec) {
int i = 0;
unsigned int highestOne = 1 << (sizeof(unsigned int)*8 - 1);
for (i = 0; i < sizeof(int)*8; i++)
printf("%d", (dec & (highestOne >> i))>> (highestOne - i - 1));
}
In particular, I don't understand how the second right shift operator in the print statement results in either a '1' or '0'.
Upvotes: 0
Views: 99
Reputation: 67721
How is this function printing an integer in binary form?
The answer is: by accident. Only because you run it on the particular hardware. But from the C point of view it should not.
This an example how to make code hard to read and understand and as a consequence wrong.
(dec & (highestOne >> i)) >> (highestOne - i - 1))
highestOne
starts from a very big number, highestOne - i - 1
will be larger than the operand size until highestOne - i - 1
is less than sizeof(int)*8
. This is an undefined behaviour. So how does this code actually work? It is only because x86 implementation of the shr
instruction actually shifts by given number of bits modulo size of the operand in bits. It will not work on most other systems.
I bet that the author (judging from the code) of the original code did it by accident.
The correct code should be (!!
gives one if number is non zero, zero otherwise):
void toBin(unsigned int dec)
{
unsigned int currentMask = 1 << (sizeof(dec) * CHAR_BIT - 1);
for (; currentMask; currentMask >>= 1)
printf("%d", !!(dec & currentMask));
fflush(stdout);
}
int main(void)
{
unsigned num;
for(int x = 1; x < 10; x++)
{
num = rand();
toBin(num); printf(" (%u)\n", num);
}
}
Upvotes: 2
Reputation: 2612
highestOne is a bitmask with a single bit in it.
The dec & ... expression is ANDing that bit mask, so if the bit in that position is preserved and all the others are zeroed out.
The second shift operator, >>, is moving that bit down to the 1s place, causing the number to be only a 0 or a 1 for the %d in the printf() statement.
The for loop is for rinse, lather, and repeating, but for successive positions.
Upvotes: -1