omnichord
omnichord

Reputation: 744

Why do these two functions to print binary representation of an integer have the same output?

I have two functions that print 32bit number in binary. First one divides the number into bytes and starts printing from the last byte (from the 25th bit of the whole integer). Second one is more straightforward and starts from the 1st bit of the number. It seems to me that these functions should have different outputs, because they process the bits in different orders. However the outputs are the same. Why?

#include <stdio.h>

void printBits(size_t const size, void const * const ptr)
{
    unsigned char *b = (unsigned char*) ptr;
    unsigned char byte;

    int i, j;

    for (i=size-1;i>=0;i--)
    {
        for (j=7;j>=0;j--)
        {

            byte = (b[i] >> j) & 1;
            printf("%u", byte);
        }
    }
    puts("");
}

void printBits_2( unsigned *A) {

    for (int i=31;i>=0;i--)
    {
    printf("%u", (A[0] >>  i ) & 1u );
    }
    puts("");
}

int main()
{
    unsigned a = 1014750;
    printBits(sizeof(a), &a); // ->00000000000011110111101111011110
    printBits_2(&a); //          ->00000000000011110111101111011110
    return 0;
}

Upvotes: 3

Views: 406

Answers (4)

Patrick Roberts
Patrick Roberts

Reputation: 51936

They don't process the bits in different orders. Here's a visual:

Bytes: 4                       3                       2                       1
Bits:  8  7  6  5  4  3  2  1  8  7  6  5  4  3  2  1  8  7  6  5  4  3  2  1  8  7  6  5  4  3  2  1
Bits:  32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1

The fact that the output is the same from both of these functions tells you that your platform uses Little-Endian encoding, which means the most significant byte comes last.

The first two rows show how the first function works on your program, and the last row shows how the second function works.

However, the first function will fail on platforms that use Big-Endian encoding and output the bits in this order shown in the third row:

Bytes: 4                       3                       2                       1
Bits:  8  7  6  5  4  3  2  1  8  7  6  5  4  3  2  1  8  7  6  5  4  3  2  1  8  7  6  5  4  3  2  1
Bits:  8  7  6  5  4  3  2  1  16 15 14 13 12 11 10 9  24 23 22 21 20 19 18 17 32 31 30 29 28 27 26 25

Upvotes: 1

Rishikesh Raje
Rishikesh Raje

Reputation: 8614

For the printbits1 function, it is taking the uint32 pointer and assigning it to a char pointer.

unsigned char *b = (unsigned char*) ptr;

Now, in a big endian processor, b[0] will point to the Most significant byte of the uint32 value. The inner loop prints this byte in binary, and then b[1] will point to the next most significant byte in ptr. Therefore this method prints the uint32 value MSB first.

As for printbits2, you are using

unsigned *A

i.e. an unsigned int. This loop runs from 31 to 0 and prints the uint32 value in binary.

Upvotes: 0

Honza Remeš
Honza Remeš

Reputation: 1193

Both your functions print binary representation of the number from the most significant bit to the least significant bit. Today's PCs (and majority of other computer architectures) use so-called Little Endian format, in which multi-byte values are stored with least significant byte first.

That means that 32-bit value 0x01020304 stored on address 0x1000 will look like this in the memory:

+--------++--------+--------+--------+--------+
|Address || 0x1000 | 0x1001 | 0x1002 | 0x1003 |
+--------++--------+--------+--------+--------+
|Data    ||  0x04  |  0x03  |  0x02  |  0x01  |
+--------++--------+--------+--------+--------+

Therefore, on Little Endian architectures, printing value's bits from MSB to LSB is equivalent to taking its bytes in reversed order and printing each byte's bits from MSB to LSB.

Upvotes: 3

Sam Varshavchik
Sam Varshavchik

Reputation: 118445

This is the expected result when:

1) You use both functions to print a single integer, in binary.

2) Your C++ implementation is on a little-endian hardware platform.

Change either one of these factors (with printBits_2 appropriately adjusted), and the results will be different.

Upvotes: 2

Related Questions