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

DoubConv.cc
Go to the documentation of this file.
1 #include "CLHEP/Random/DoubConv.hh"
2 
3 #include <sstream>
4 #include <iomanip>
5 
6 namespace CLHEP {
7 
8 bool DoubConv::byte_order_known = false;
9 int DoubConv::byte_order[8];
10 
11 void 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 
78 std::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 
90 std::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 
106 double 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