Re: write binary representation to output
On 19 avr, 10:51, "Alf P. Steinbach" <al...@start.no> wrote:
* wongjoek...@yahoo.com:
I was wondering how in C++ the code would look like if I
want to write the binary notation of a unsigned char to
standard output or any other basic data type, like int,
unsigned int, float and so forth.
E.g.
<code>
#include <iostream> // std::cout, std::ostream
#include <ostream> // operator<<, std::endl
#include <bitset> // std::bits
#include <climits> // CHAR_BIT
static unsigned const bitsPerByte = CHAR_BIT;
template< typename T >
struct BitSize
{
enum { value = bitsPerByte*sizeof( T ) };
};
Just curious, but do you really need this?
template< typename T >
std::bitset< BitSize<T>::value > bitsetFrom( T const& v )
{
typedef std::bitset< BitSize<T>::value > BitSet;
BitSet result;
unsigned char const* p = reinterpret_cast<unsigned char const*=
( & v );
And why this?
// Uses little-endian convention for bit numbering.
Which I think the standard requires. The problem is that you're
also assuming little-endian for the byte order, which is the
exception, not the rule (in terms of number of architectures,
not number of machines).
for( size_t i = sizeof(T)-1; i != size_t(-1); --i )
{
result <<= bitsPerByte;
result |= BitSet( p[i] );
}
return result;
}
Maybe I'm misunderstanding something, but when someone says
somthine like "binary notation to standard out", I imagine
something like "00011100" (for 0x1C). I'm not really sure what
he's looking for when he mentions float, but for the unsigned
integral types, something like the following should do as a
first approximation:
template< typename T >
class Binary
{
public:
explicit Binary( T value )
: myValue( value )
{
}
friend std::ostream&operator<<(
std::ostream& dest,
Binary< T > const& value )
{
T tmp = value.myValue ;
std::string s ;
do {
s += '0' + (tmp & 1) ;
tmp >>= 1 ;
} while ( tmp != 0 ) ;
reverse( s.begin(), s.end() ) ;
dest << s ;
return dest ;
}
} ;
template< typename T >
inline Binary< T >
binary( T value )
{
return Binary< T >( value ) ;
}
Use:
unsigned i = 42 ;
std::cout << binary( i ) << std::endl ;
Most of the formatting flags (e.g. width) are handled correctly,
by the << operator for string.
Handling signed values is a bit more tricky, because you need
the unsigned equivalent for the tmp, or else some special code
for handling the the fact that on most machines, there is one
negative value which doesn't have a positive corresponant. (If
you're lucky enough to be working on a 1's complement machine or
a signed magnitude machine, there's no problem.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34