Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
BitReproducible.cxx
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Authors: W. Brown, M. Fischler, L. Moneta 2005
3 
5 
6 #include <sstream>
7 #include <iomanip>
8 #include <exception>
9 
10 namespace ROOT {
11 namespace Math {
12 namespace GenVector_detail {
13 
14 bool BitReproducible::fgByte_order_known = false;
15 int BitReproducible::fgByte_order[8];
16 
17 void BitReproducible::Fill_byte_order () {
18  // Fill_byte_order
19  double x = 1.0;
20  int t30 = 1 << 30;
21  int t22 = 1 << 22;
22  x *= t30;
23  x *= t22;
24  double y = 1;
25  double z = 1;
26  x *= z;
27  for (int k=0; k<6; k++) {
28  x += y*z;
29  y += 1;
30  z *= 256;
31  }
32  // x, in IEEE format, would now be 0x4330060504030201
33  DB8 xb;
34  xb.fD = x;
35  int n;
36  static const int kUNSET = -1;
37  for (n=0; n<8; n++) {
38  fgByte_order[n] = kUNSET;
39  }
40  int order;
41  for (n=0; n<8; n++) {
42  switch ( xb.fB[n] ) {
43  case 0x43:
44  order = 0;
45  break;
46  case 0x30:
47  order = 1;
48  break;
49  case 0x06:
50  order = 2;
51  break;
52  case 0x05:
53  order = 3;
54  break;
55  case 0x04:
56  order = 4;
57  break;
58  case 0x03:
59  order = 5;
60  break;
61  case 0x02:
62  order = 6;
63  break;
64  case 0x01:
65  order = 7;
66  break;
67  default:
68  throw BitReproducibleException(
69  "Cannot determine byte-ordering of doubles on this system");
70  }
71  if (fgByte_order[n] != kUNSET) {
72  throw BitReproducibleException(
73  "Confusion in byte-ordering of doubles on this system");
74  }
75  fgByte_order[n] = order;
76  fgByte_order_known = true;
77  }
78  return;
79 }
80 
81 std::string BitReproducible::D2x(double d) {
82  // hex conversion
83  if ( !fgByte_order_known ) Fill_byte_order ();
84  DB8 db;
85  db.fD = d;
86  std::ostringstream ss;
87  for (int i=0; i<8; ++i) {
88  int k = fgByte_order[i];
89  ss << std::hex << std::setw(2) << std::setfill('0') << (int)db.fB[k];
90  }
91  return ss.str();
92 }
93 
94 void BitReproducible::Dto2longs(double d, unsigned int& i, unsigned int& j) {
95  // conversion to 2 longs
96  if ( !fgByte_order_known ) Fill_byte_order ();
97  DB8 db;
98  db.fD = d;
99  i = ((static_cast<unsigned int>(db.fB[fgByte_order[0]])) << 24)
100  | ((static_cast<unsigned int>(db.fB[fgByte_order[1]])) << 16)
101  | ((static_cast<unsigned int>(db.fB[fgByte_order[2]])) << 8)
102  | ((static_cast<unsigned int>(db.fB[fgByte_order[3]])) );
103  j = ((static_cast<unsigned int>(db.fB[fgByte_order[4]])) << 24)
104  | ((static_cast<unsigned int>(db.fB[fgByte_order[5]])) << 16)
105  | ((static_cast<unsigned int>(db.fB[fgByte_order[6]])) << 8)
106  | ((static_cast<unsigned int>(db.fB[fgByte_order[7]])) );
107 }
108 
109 double BitReproducible::Longs2double (unsigned int i, unsigned int j) {
110  // conversion longs to double
111  DB8 db;
112  unsigned char bytes[8];
113  if ( !fgByte_order_known ) Fill_byte_order ();
114  bytes[0] = static_cast<unsigned char>((i >> 24) & 0xFF);
115  bytes[1] = static_cast<unsigned char>((i >> 16) & 0xFF);
116  bytes[2] = static_cast<unsigned char>((i >> 8) & 0xFF);
117  bytes[3] = static_cast<unsigned char>((i ) & 0xFF);
118  bytes[4] = static_cast<unsigned char>((j >> 24) & 0xFF);
119  bytes[5] = static_cast<unsigned char>((j >> 16) & 0xFF);
120  bytes[6] = static_cast<unsigned char>((j >> 8) & 0xFF);
121  bytes[7] = static_cast<unsigned char>((j ) & 0xFF);
122  for (int k=0; k<8; ++k) {
123  db.fB[fgByte_order[k]] = bytes[k];
124  }
125  return db.fD;
126 }
127 
128 } // namespace _GenVector_detail
129 } // namespace Math
130 } // namespace ROOT