|
||||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |