Reputation: 3747
In 'Thinking in C++' by Bruce Eckel, there is a program given to print a double value
in binary. (Chapter 3, page no. 189)
int main(int argc, char* argv[])
{
if(argc != 2)
{
cout << "Must provide a number" << endl;
exit(1);
}
double d = atof(argv[1]);
unsigned char* cp = reinterpret_cast<unsigned char*>(&d);
for(int i = sizeof(double); i > 0 ; i -= 2)
{
printBinary(cp[i-1]);
printBinary(cp[i]);
}
}
Here while printing cp[i] when i=8 (assuming double is of 8 bytes), wouldn't it be undefined behaviour?
I mean this code doesn't work as it doesn't print cp[0].
Upvotes: 4
Views: 2413
Reputation: 3512
You can do this in an endian-independent way, by casting the double to an unsigned long long. Then you can use simple bit shifting on the integer to access and print the bits, from bit 0 to bit 63.
(I've written a C function called "print_raw_double_binary() that does this -- see my article Displaying the Raw Fields of a Floating-Point Number for details.)
Upvotes: 0
Reputation: 754010
A1: Yes, it would be undefined behaviour when it accesses cp[8].
A2: Yes, it also does not print cp[0].
As shown, it prints bytes 7, 8, 5, 6, 3, 4, 2, 1 of the valid values 0..7. So, if you have copied the code correctly from the book, there is a bug in the book's code. Check the errata page for the book, if there is one.
It is also odd that it unwinds the loop; a simpler formulation is:
for (int i = sizeof(double); i-- > 0; )
printBinary(cp[i]);
There is also, presumably, a good reason for printing the bytes in reverse order; it is not obvious what that would be.
Upvotes: 4
Reputation: 58780
It looks like a typo in the book's code. The second call should probably be printBinary(cp[i-2])
.
This is a bit wierd though, because they're reversing the byte order compared to what's actually in memory (IEEE 754 floating point numbers have no rules about endianness, so I guess it's valid on his platform), and because he's counting by 2 instead of just 1.
It would be simpler to write
for(int i = 0; i != sizeof(double) ; ++i) printBinary(cp[i]);
or (if reversing the bytes is important) use the standard idiom for a loop that counts down
for(int i = sizeof(double); (i--) > 0;) printBinary(cp[i]);
Upvotes: 2