Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:21:56

0001 // @(#)root/mathcore:$Id$
0002 // Authors: W. Brown, M. Fischler, L. Moneta    2005
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2005 , LCG / FNAL ROOT MathLib Team                  *
0007  *                                                                    *
0008  *                                                                    *
0009  **********************************************************************/
0010 
0011 // Header file for class LorentzVector
0012 //
0013 // Created by: fischler  at Mon Jun 25  2005
0014 //
0015 // Last update: $Id$
0016 //
0017 #ifndef ROOT_Math_GenVector_BitReproducible
0018 #define ROOT_Math_GenVector_BitReproducible  1
0019 
0020 #include <iostream>
0021 #include <string>
0022 #include <exception>
0023 
0024 #include <iomanip>
0025 
0026 namespace ROOT {
0027  namespace Math {
0028   namespace GenVector_detail {
0029 
0030 class BitReproducibleException  : public std::exception
0031 {
0032 public:
0033   BitReproducibleException(const std::string & w) noexcept : fMsg(w) {}
0034   ~BitReproducibleException() noexcept override {}
0035   const char *what() const noexcept override { return fMsg.c_str(); }
0036   private:
0037   std::string fMsg;
0038 };
0039 
0040 class BitReproducible {
0041 public:
0042 
0043   // dto2longs(d, i1, i2) returns (in i1 and i2) two unsigned ints
0044   // representation of its double input.  This is byte-ordering
0045   // independent, and depends for complete portability ONLY on adherence
0046   // to the IEEE 754 standard for 64-bit floating point representation.
0047   // The first unsigned int contains the high-order bits in IEEE; thus
0048   // 1.0 will always be 0x3FF00000, 00000000
0049   static void Dto2longs(double d, unsigned int & i1, unsigned int & i2);
0050 
0051   // longs2double (i1,i2) returns a double containing the value represented by
0052   // its input, which must be a 2 unsigned ints.
0053   // The input is taken to be the representation according to
0054   // the IEEE 754 standard for a 64-bit floating point number, whose value
0055   // is returned as a double.  The byte-ordering of the double result is,
0056   // of course, tailored to the proper byte-ordering for the system.
0057   static double Longs2double (unsigned int i1, unsigned int i2);
0058 
0059   // dtox(d) returns a 16-character string containing the (zero-filled) hex
0060   // representation of its double input.  This is byte-ordering
0061   // independent, and depends for complete portability ONLY on adherence
0062   // to the IEEE 754 standard for 64-bit floating point representation.
0063   static std::string D2x(double d);
0064 
0065   static void Output ( std::ostream & os, double d ) {
0066     unsigned int i1, i2;
0067     Dto2longs(d, i1, i2);
0068     os << " " << i1 << " " << i2;
0069   }
0070 
0071   static void Input ( std::istream & is, double & d ) {
0072     unsigned int i1, i2;
0073     is >> i1 >> i2;
0074     d = Longs2double(i1, i2);
0075   }
0076 
0077   static void Output ( std::ostream & os, float f ) {
0078     unsigned int i1, i2;
0079     Dto2longs( double(f), i1, i2 );
0080     os << " " << i1 << " " << i2;
0081   }
0082 
0083   static void Input ( std::istream & is, float & f ) {
0084     unsigned int i1, i2;
0085     is >> i1 >> i2;
0086     f = float( Longs2double(i1, i2) );
0087   }
0088 
0089 
0090 private:
0091   union DB8 {
0092     unsigned char fB[8];
0093     double fD;
0094   };
0095   static void Fill_byte_order ();
0096   static bool fgByte_order_known;
0097   static int  fgByte_order[8];
0098     // Meaning of byte_order:  The first (high-order in IEEE 754) byte to
0099     // output (or the high-order byte of the first unsigned int)
0100     // is  of db.b[byte_order[0]].  Thus the index INTO byte_order
0101     // is a position in the IEEE representation of the double, and the value
0102     // of byte_order[k] is an offset in the memory representation of the
0103     // double.
0104 
0105 };  // BitReproducible
0106 
0107 }  // namespace _GenVector_detail
0108 }  // namespace Math
0109 }  // namespace ROOT
0110 
0111 // A note about floats and long doubles:
0112 //
0113 // BitReproducible can be used with floats by doing the equivalent of
0114 //   float x = x0; BitReproducible::dto2longs (x, i, j);
0115 //   float y = BitReproducible::longs2double (i, j);
0116 // The results are correct.
0117 // The only inefficiency is that two integers are used where one would suffice.
0118 //
0119 // The same artifice will compile for long double.  However, any value of the
0120 // long double which is not precisely representable as a double will not
0121 // give exact results for the read-back.
0122 //
0123 // We intend in the near future to create a templated version of this class
0124 // which cures both the above flaws.  (In the case of long double, this is
0125 // contingent upon finding some IEEE standard for the bits in a 128-bit double.)
0126 
0127 
0128 #endif // DOUBCONV_HH