// bits.cc
// Darstellung der Bit-Codierung der verschiedenen elementaren Datentypen
// ist stark abhaengig von der Rechnerarchitektur!!

#include <iostream>
#include <typeinfo>    // fuer typeid
using namespace std;

template <class T>
void bits(ostream &os, const T& x) {
  char *p = (char *) &x;        // Wandle Adresse von x in char-Adresse
  int   k = sizeof(x);
  if (typeid(x) == typeid((long double)1.0)) k = 10;  // nur 10 Byte verwendet!
  // 32bit-Linux oder -m96bit-long-double:  12 Byte Speicher, 10 Byte Praezision
  // 64bit-Linux oder -m128bit-long-double: 16 Byte Speicher, 10 Byte Praezision
  for (int i = k-1; i >= 0; i--) {      // Durchlaufen der Bytes von x
    for (int c = 128; c > 0; c >>= 1)   // ein Byte bitweise ausgeben
      os << ( p[i] & c ? 1 : 0 );
    os << " ";                          // Trennung der Bytes
  }
  os << "\n";
}

int main() {
  char c;int i; long long ll;
  float f; double d; long double ld;
  // Ausgabe der Groessen
  cout << "sizeof(char)        =  " << sizeof(char)        << "\n";
  cout << "sizeof(int)         =  " << sizeof(int)         << "\n";
  cout << "sizeof(long long)   =  " << sizeof(long long)   << "\n";
  cout << "sizeof(float)       =  " << sizeof(float)       << "\n";
  cout << "sizeof(double)      =  " << sizeof(double)      << "\n";
  cout << "sizeof(long double) =  " << sizeof(long double) << "\n";
  while (1) {
    cout << " : "; cin >> ld;
    // Umwandlung per cast
    c  = (char) ld; i = (int) ld; ll = (long long) ld;
    f = (float) ld; d = (double) ld;
    // Ausgabe:
    bits(cout,c); bits(cout,i); bits(cout,ll);
    bits(cout,f); bits(cout,d); bits(cout,ld);
  }
}
