Happy Mittal
Happy Mittal

Reputation: 3747

printing double in binary

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

Answers (3)

Rick Regan
Rick Regan

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

Jonathan Leffler
Jonathan Leffler

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

Ken Bloom
Ken Bloom

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

Related Questions