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