BitReproducible.cxx

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: BitReproducible.cxx 22516 2008-03-07 15:14:26Z moneta $
00002 // Authors: W. Brown, M. Fischler, L. Moneta    2005  
00003 
00004 #include "Math/GenVector/BitReproducible.h"
00005 
00006 #include <sstream>
00007 #include <iomanip>
00008 #include <exception>
00009 
00010 namespace ROOT { 
00011 namespace Math { 
00012 namespace GenVector_detail {
00013 
00014 bool BitReproducible::fgByte_order_known = false;
00015 int  BitReproducible::fgByte_order[8];
00016 
00017 void BitReproducible::Fill_byte_order () {
00018    // Fill_byte_order
00019    double x = 1.0;
00020    int t30 = 1 << 30;
00021    int t22 = 1 << 22;
00022    x *= t30;
00023    x *= t22;
00024    double y = 1;
00025    double z = 1;
00026    x *= z;
00027    for (int k=0; k<6; k++) {
00028       x += y*z;
00029       y += 1;
00030       z *= 256;
00031    }
00032    // x, in IEEE format, would now be 0x4330060504030201
00033    union DB8 {
00034       unsigned char fB[8];
00035       double fD;
00036    };
00037    DB8 xb;
00038    xb.fD = x;
00039    int n;
00040    static const int kUNSET = -1;
00041    for (n=0; n<8; n++) {
00042       fgByte_order[n] = kUNSET;
00043    }
00044    int order;
00045    for (n=0; n<8; n++) {
00046       switch ( xb.fB[n] ) {
00047          case 0x43:
00048             order = 0;
00049             break;
00050          case 0x30:
00051             order = 1;
00052             break;
00053          case 0x06:
00054             order = 2;
00055             break;
00056          case 0x05:
00057             order = 3;
00058             break;
00059          case 0x04:
00060             order = 4;
00061             break;
00062          case 0x03:
00063             order = 5;
00064             break;
00065          case 0x02:
00066             order = 6;
00067             break;
00068          case 0x01:
00069             order = 7;
00070             break;
00071          default:
00072             throw BitReproducibleException(
00073                                            "Cannot determine byte-ordering of doubles on this system");
00074       }
00075       if (fgByte_order[n] != kUNSET) {
00076          throw BitReproducibleException(
00077                                         "Confusion in byte-ordering of doubles on this system");
00078       }
00079       fgByte_order[n] = order;
00080       fgByte_order_known = true;
00081    }
00082    return;
00083 }
00084 
00085 std::string BitReproducible::D2x(double d) {
00086    // hex conversion
00087    if ( !fgByte_order_known ) Fill_byte_order ();
00088    DB8 db;
00089    db.fD = d;
00090    std::ostringstream ss;
00091    for (int i=0; i<8; ++i) {
00092       int k = fgByte_order[i];
00093       ss << std::hex << std::setw(2) << std::setfill('0') << (int)db.fB[k];
00094    }
00095    return ss.str();
00096 }
00097 
00098 void BitReproducible::Dto2longs(double d, unsigned int& i, unsigned int& j) {
00099    // conversion to 2 longs
00100    if ( !fgByte_order_known ) Fill_byte_order ();
00101    DB8 db;
00102    db.fD = d;
00103    i    =   ((static_cast<unsigned int>(db.fB[fgByte_order[0]])) << 24)
00104       | ((static_cast<unsigned int>(db.fB[fgByte_order[1]])) << 16)
00105       | ((static_cast<unsigned int>(db.fB[fgByte_order[2]])) <<  8)
00106       | ((static_cast<unsigned int>(db.fB[fgByte_order[3]]))      );
00107    j    =   ((static_cast<unsigned int>(db.fB[fgByte_order[4]])) << 24)
00108       | ((static_cast<unsigned int>(db.fB[fgByte_order[5]])) << 16)
00109       | ((static_cast<unsigned int>(db.fB[fgByte_order[6]])) <<  8)
00110       | ((static_cast<unsigned int>(db.fB[fgByte_order[7]]))      );
00111 }
00112 
00113 double BitReproducible::Longs2double (unsigned int i, unsigned int j) {
00114    // conversion longs to double
00115    DB8 db;
00116    unsigned char bytes[8];
00117    if ( !fgByte_order_known ) Fill_byte_order ();
00118    bytes[0] = static_cast<unsigned char>((i >> 24) & 0xFF);
00119    bytes[1] = static_cast<unsigned char>((i >> 16) & 0xFF);
00120    bytes[2] = static_cast<unsigned char>((i >>  8) & 0xFF);
00121    bytes[3] = static_cast<unsigned char>((i      ) & 0xFF);
00122    bytes[4] = static_cast<unsigned char>((j >> 24) & 0xFF);
00123    bytes[5] = static_cast<unsigned char>((j >> 16) & 0xFF);
00124    bytes[6] = static_cast<unsigned char>((j >>  8) & 0xFF);
00125    bytes[7] = static_cast<unsigned char>((j      ) & 0xFF);
00126    for (int k=0; k<8; ++k) {
00127       db.fB[fgByte_order[k]] =  bytes[k];
00128    }
00129    return db.fD;
00130 }
00131 
00132 }  // namespace _GenVector_detail
00133 }  // namespace Math
00134 }  // namespace ROOT

Generated on Tue Jul 5 14:30:52 2011 for ROOT_528-00b_version by  doxygen 1.5.1