00001
00002
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
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
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
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
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
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 }
00133 }
00134 }