Re: Bit-Pattern of Representation of Objects
Robbie Hatley wrote:
"Alf P. Steinbach" <alfps@start.no> wrote:
Robbie Hatley wrote:
...
size_t size = 8 * sizeof(object); // Size of object in bits.
Use CHAR_BITS or whatever it's called: a byte isn't necessarily 8 bits.
"CHAR_BIT". True. However, the vast majority of the world's computers,
especially non-mainframe computers, use 8-bit bytes. That's pretty
ubiquitous.
But to be pedantic, I'll do:
size_t size = CHAR_BIT * sizeof(object);
unsigned long long int mask =
C++ does not have a 'long long' type, yet.
Not yet, but the committe is working on it. Besides, many
C++ compilers jumped the gun and provided long long and
unsigned long long years ago, so they're actually quite common.
static_cast<unsigned long long int>
(pow(2.0, static_cast<double>(size - 1)) + 0.1);
Use left shift operator.
Great idea! Thanks! Saves the inefficient pow() call.
I'll do this:
unsigned long long mask = unsigned long long(1) << size - 1;
unsigned long long int pattern =
*reinterpret_cast<const unsigned long long int*>(&object);
You don't know that sizeopf(object) <= sizeof(long long).
Yes, I do. Think about it. Unsigned long long has a maximum
value of over 18 quintillion, so it can express the size of
an object of over 18EB. ("EB" is "exabytes". One exabyte
is 10^18 bytes, or 1 billion gigabytes.) You give me a computer
with 18EB of memory, I'll give you $500 for it. :-)
You are aguing
sizeof(object) <= std::max<long long>()
not
sizeof( object ) <= sizeof( long long )
Note sizeof(long long) maybe as low as 8 (or even 1 if chars are really
huge).
Anyway, what happens in the code is that you try to store the bit pattern of
object in a variable of type unsigned long long, whose size might be too
small. So what about:
#include <cstddef>
#include <climits>
template < typename T >
struct bit_pattern {
static std::size_t const size = sizeof( T );
typedef unsigned char const * address;
static
address mem_location ( T const & t ) {
return ( reinterpret_cast< address >( &t ) );
}
template < typename OutIter >
static
OutIter dump_bits ( T const & t, OutIter where ) {
address loc = mem_location( t );
for ( std::size_t index = 0; index < size; ++index ) {
unsigned char c = loc[index];
unsigned char mask = 1;
for ( std::size_t bit_pos = 0; bit_pos < CHAR_BIT; ++ bit_pos ) {
where = ( ( c & mask ) != 0 );
++ where;
mask <<= 1;
}
}
return ( where );
}
}; // bit_pattern
template < typename T, typename OutIter >
OutIter dump_bits ( T const & t, OutIter where ) {
return ( bit_pattern<T>::dump_bits( t, where ) );
}
#include <iostream>
#include <iterator>
int main ( void ) {
int i = 5;
std::ostream_iterator< bool > bool_writer ( std::cout );
dump_bits( i, bool_writer );
std::cout << '\n';
}
Best
Kai-Uwe Bux