CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

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