CLHEP 2.0.4.7 Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 #include "CLHEP/Random/DoubConv.hh" 00002 00003 #include <sstream> 00004 #include <iomanip> 00005 00006 namespace CLHEP { 00007 00008 bool DoubConv::byte_order_known = false; 00009 int DoubConv::byte_order[8]; 00010 00011 void DoubConv::fill_byte_order () { 00012 double x = 1.0; 00013 int t30 = 1 << 30; 00014 int t22 = 1 << 22; 00015 x *= t30; 00016 x *= t22; 00017 double y = 1; 00018 double z = 1; 00019 x *= z; 00020 for (int k=0; k<6; k++) { 00021 x += y*z; 00022 y += 1; 00023 z *= 256; 00024 } 00025 // x, in IEEE format, would now be 0x4330060504030201 00026 union DB8 { 00027 unsigned char b[8]; 00028 double d; 00029 }; 00030 DB8 xb; 00031 xb.d = x; 00032 int n; 00033 static const int UNSET = -1; 00034 for (n=0; n<8; n++) { 00035 byte_order[n] = UNSET; 00036 } 00037 int order; 00038 for (n=0; n<8; n++) { 00039 switch ( xb.b[n] ) { 00040 case 0x43: 00041 order = 0; 00042 break; 00043 case 0x30: 00044 order = 1; 00045 break; 00046 case 0x06: 00047 order = 2; 00048 break; 00049 case 0x05: 00050 order = 3; 00051 break; 00052 case 0x04: 00053 order = 4; 00054 break; 00055 case 0x03: 00056 order = 5; 00057 break; 00058 case 0x02: 00059 order = 6; 00060 break; 00061 case 0x01: 00062 order = 7; 00063 break; 00064 default: 00065 throw DoubConvException( 00066 "Cannot determine byte-ordering of doubles on this system"); 00067 } 00068 if (byte_order[n] != UNSET) { 00069 throw DoubConvException( 00070 "Confusion in byte-ordering of doubles on this system"); 00071 } 00072 byte_order[n] = order; 00073 byte_order_known = true; 00074 } 00075 return; 00076 } 00077 00078 std::string DoubConv::d2x(double d) { 00079 if ( !byte_order_known ) fill_byte_order (); 00080 DB8 db; 00081 db.d = d; 00082 std::ostringstream ss; 00083 for (int i=0; i<8; ++i) { 00084 int k = byte_order[i]; 00085 ss << std::hex << std::setw(2) << std::setfill('0') << (int)db.b[k]; 00086 } 00087 return ss.str(); 00088 } 00089 00090 std::vector<unsigned long> DoubConv::dto2longs(double d) { 00091 std::vector<unsigned long> v(2); 00092 if ( !byte_order_known ) fill_byte_order (); 00093 DB8 db; 00094 db.d = d; 00095 v[0] = ((static_cast<unsigned long>(db.b[byte_order[0]])) << 24) 00096 | ((static_cast<unsigned long>(db.b[byte_order[1]])) << 16) 00097 | ((static_cast<unsigned long>(db.b[byte_order[2]])) << 8) 00098 | ((static_cast<unsigned long>(db.b[byte_order[3]])) ); 00099 v[1] = ((static_cast<unsigned long>(db.b[byte_order[4]])) << 24) 00100 | ((static_cast<unsigned long>(db.b[byte_order[5]])) << 16) 00101 | ((static_cast<unsigned long>(db.b[byte_order[6]])) << 8) 00102 | ((static_cast<unsigned long>(db.b[byte_order[7]])) ); 00103 return v; 00104 } 00105 00106 double DoubConv::longs2double (const std::vector<unsigned long> & v) { 00107 DB8 db; 00108 unsigned char bytes[8]; 00109 if ( !byte_order_known ) fill_byte_order (); 00110 bytes[0] = static_cast<unsigned char>((v[0] >> 24) & 0xFF); 00111 bytes[1] = static_cast<unsigned char>((v[0] >> 16) & 0xFF); 00112 bytes[2] = static_cast<unsigned char>((v[0] >> 8) & 0xFF); 00113 bytes[3] = static_cast<unsigned char>((v[0] ) & 0xFF); 00114 bytes[4] = static_cast<unsigned char>((v[1] >> 24) & 0xFF); 00115 bytes[5] = static_cast<unsigned char>((v[1] >> 16) & 0xFF); 00116 bytes[6] = static_cast<unsigned char>((v[1] >> 8) & 0xFF); 00117 bytes[7] = static_cast<unsigned char>((v[1] ) & 0xFF); 00118 for (int i=0; i<8; ++i) { 00119 db.b[byte_order[i]] = bytes[i]; 00120 } 00121 return db.d; 00122 } 00123 00124 } // end namespace HepMC