For readers who skim, I'll start with a question (instead of burying it
below):
*** Is there a C++ library function that prints binary representations
of numbers?
Continuing. Thanks for the explanations. I was wondering yesterday
whether -0 had a different bit representation from 0. I thought how
terrible it would be if -0 *did* have a different bit representation
from 0, and NULL were defined as -0, and someone wrote an if-test that
relied on NULL being 0.
e.g.,
#define NULL -0 // redefine the NULL macro
....
char* buf = (char*)malloc(sizeof(char)*N);
if (!buf) { // if NULL has a nonzero bit representation, this will fail!
exit(1);
}
I think we should rely on bit representations of things only when we
have to (e.g., low-level file processing) or when we're trying to make
programs run more efficiently (e.g., bit ops). And I stop here because I
haven't done much of either of these.
Below is a little program I wrote to print binary representations. Yeah,
most of us have probably written one of these. If a C++ library function
exists for this, I feel silly.
I thought that actually *printing* bit representations was necessary to
show that the bit representations of -0 and 0 differ, because C++ can do
typecasts behind your back (e.g., from -0 to 0? I didn't know and didn't
want to take a chance).
--Suzanne
------------------------------------------------------------------------------------
// File: BitRepresentationsMain.cpp
#include <iostream>
///////////////////////////////////////////////////////////////////////////////
// TYPEDEFS AND CONSTANTS
///////////////////////////////////////////////////////////////////////////////
const int NUM_BITS_PER_CHAR = 8;
///////////////////////////////////////////////////////////////////////////////
// UTILITY FUNCTIONS
///////////////////////////////////////////////////////////////////////////////
// Convert integer n to a null-terminated string of 0's and 1's
representing its
// binary representation.
template<class T>
char* toBinary(char* binary, T n)
{
// Advance the pointer all the way to the right.
long nbits = sizeof(T) * NUM_BITS_PER_CHAR;
binary += nbits;
// Append null.
*binary = '\0';
binary--;
// Write chars via the pointer.
for (int i=0; i < nbits; i++)
{
*binary = (n & 1)==1 ? '1' : '0';
n = n >> 1;
binary--;
}
binary++;
return binary;
}
///////////////////////////////////////////////////////////////////////////////
// MAIN
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
char* binary = (char*)malloc(sizeof(long) * NUM_BITS_PER_CHAR + 1);
std::cout << "-0:\t" << toBinary<int>(binary, int(-0)) << "\n";
std::cout << "0:\t" << toBinary<int>(binary, int(0)) << "\n";
std::cout << "-0:\t" << toBinary<long>(binary, long(-0)) << "\n";
std::cout << "0:\t" << toBinary<long>(binary, long(0)) << "\n";
std::cout << "-0:\t" << toBinary<char>(binary, char(-0)) << "\n";
std::cout << "0:\t" << toBinary<char>(binary, char(0)) << "\n";
for (int i=-3; i<=3; i++)
{
std::cout << i << ":\t" << toBinary<int>(binary, int(i)) << "\n";
}
free(binary);
return EXIT_SUCCESS;
}