1 #include "CLHEP/Random/DoubConv.hh" 2 3 #include <sstream> 4 #include <iomanip> 5 6 namespace CLHEP { 7 8 CLHEP_THREAD_LOCAL bool DoubConv::byte_order_known = false; 9 CLHEP_THREAD_LOCAL int DoubConv::byte_order[8]; 10 fill_byte_order()11void DoubConv::fill_byte_order () { 12 double x = 1.0; 13 int t30 = 1 << 30; 14 int t22 = 1 << 22; 15 x *= t30; 16 x *= t22; 17 double y = 1; 18 double z = 1; 19 x *= z; 20 for (int k=0; k<6; k++) { 21 x += y*z; 22 y += 1; 23 z *= 256; 24 } 25 // x, in IEEE format, would now be 0x4330060504030201 26 DB8 xb; 27 xb.d = x; 28 int n; 29 static const int UNSET = -1; 30 for (n=0; n<8; n++) { 31 byte_order[n] = UNSET; 32 } 33 int order; 34 for (n=0; n<8; n++) { 35 switch ( xb.b[n] ) { 36 case 0x43: 37 order = 0; 38 break; 39 case 0x30: 40 order = 1; 41 break; 42 case 0x06: 43 order = 2; 44 break; 45 case 0x05: 46 order = 3; 47 break; 48 case 0x04: 49 order = 4; 50 break; 51 case 0x03: 52 order = 5; 53 break; 54 case 0x02: 55 order = 6; 56 break; 57 case 0x01: 58 order = 7; 59 break; 60 default: 61 throw DoubConvException( 62 "Cannot determine byte-ordering of doubles on this system"); 63 } 64 if (byte_order[n] != UNSET) { 65 throw DoubConvException( 66 "Confusion in byte-ordering of doubles on this system"); 67 } 68 byte_order[n] = order; 69 byte_order_known = true; 70 } 71 return; 72 } 73 d2x(double d)74std::string DoubConv::d2x(double d) { 75 if ( !byte_order_known ) fill_byte_order (); 76 DB8 db; 77 db.d = d; 78 std::ostringstream ss; 79 for (int i=0; i<8; ++i) { 80 int k = byte_order[i]; 81 ss << std::hex << std::setw(2) << std::setfill('0') << (int)db.b[k]; 82 } 83 return ss.str(); 84 } 85 dto2longs(double d)86std::vector<unsigned long> DoubConv::dto2longs(double d) { 87 std::vector<unsigned long> v(2); 88 if ( !byte_order_known ) fill_byte_order (); 89 DB8 db; 90 db.d = d; 91 v[0] = ((static_cast<unsigned long>(db.b[byte_order[0]])) << 24) 92 | ((static_cast<unsigned long>(db.b[byte_order[1]])) << 16) 93 | ((static_cast<unsigned long>(db.b[byte_order[2]])) << 8) 94 | ((static_cast<unsigned long>(db.b[byte_order[3]])) ); 95 v[1] = ((static_cast<unsigned long>(db.b[byte_order[4]])) << 24) 96 | ((static_cast<unsigned long>(db.b[byte_order[5]])) << 16) 97 | ((static_cast<unsigned long>(db.b[byte_order[6]])) << 8) 98 | ((static_cast<unsigned long>(db.b[byte_order[7]])) ); 99 return v; 100 } 101 longs2double(const std::vector<unsigned long> & v)102double DoubConv::longs2double (const std::vector<unsigned long> & v) { 103 DB8 db; 104 unsigned char bytes[8]; 105 if ( !byte_order_known ) fill_byte_order (); 106 bytes[0] = static_cast<unsigned char>((v[0] >> 24) & 0xFF); 107 bytes[1] = static_cast<unsigned char>((v[0] >> 16) & 0xFF); 108 bytes[2] = static_cast<unsigned char>((v[0] >> 8) & 0xFF); 109 bytes[3] = static_cast<unsigned char>((v[0] ) & 0xFF); 110 bytes[4] = static_cast<unsigned char>((v[1] >> 24) & 0xFF); 111 bytes[5] = static_cast<unsigned char>((v[1] >> 16) & 0xFF); 112 bytes[6] = static_cast<unsigned char>((v[1] >> 8) & 0xFF); 113 bytes[7] = static_cast<unsigned char>((v[1] ) & 0xFF); 114 for (int i=0; i<8; ++i) { 115 db.b[byte_order[i]] = bytes[i]; 116 } 117 return db.d; 118 } 119 120 } // end namespace CLHEP 121