Saeed Raffoul
Saeed Raffoul

Reputation: 31

How is this function printing an integer in binary form?

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

Answers (2)

0___________
0___________

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

Walt Stoneburner
Walt Stoneburner

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

Related Questions