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