Hermes
e_float.h
Go to the documentation of this file.
1 
32 #ifndef HERMES_HERMES_NUMERIC_E_FLOAT_H
33 #define HERMES_HERMES_NUMERIC_E_FLOAT_H
34 
36 
37 namespace hermes {
38 
39 // *********************************************************************************************************************
40 // EFloat
41 // *********************************************************************************************************************
47 class EFloat {
48 public:
49  // *******************************************************************************************************************
50  // STATIC METHODS
51  // *******************************************************************************************************************
52  // *******************************************************************************************************************
53  // FRIEND FUNCTIONS
54  // *******************************************************************************************************************
55  // arithmetic
56  HERMES_DEVICE_CALLABLE inline friend EFloat operator*(f32 f, EFloat fe) { return EFloat(f) * fe; }
57  HERMES_DEVICE_CALLABLE inline friend EFloat operator/(f32 f, EFloat fe) { return EFloat(f) / fe; }
58  HERMES_DEVICE_CALLABLE inline friend EFloat operator+(f32 f, EFloat fe) { return EFloat(f) + fe; }
59  HERMES_DEVICE_CALLABLE inline friend EFloat operator-(f32 f, EFloat fe) { return EFloat(f) - fe; }
60  // *******************************************************************************************************************
61  // CONSTRUCTORS
62  // *******************************************************************************************************************
68  HERMES_DEVICE_CALLABLE explicit EFloat(f32 v, f32 e = 0.f) : v(v) {
69 #ifdef NDEBUG
70  ld = v;
71 #endif
72  if (e == 0.)
73  err.low = err.high = v;
74  else {
75  err.low = Numbers::nextFloatDown(v);
76  err.high = Numbers::nextFloatUp(v);
77  }
78  }
79  // assignment
80  // *******************************************************************************************************************
81  // OPERATORS
82  // *******************************************************************************************************************
83  // casting
86  HERMES_DEVICE_CALLABLE explicit operator float() const { return v; }
89  HERMES_DEVICE_CALLABLE explicit operator double() const { return v; }
90  // assignment
91  // arithmetic
92  HERMES_DEVICE_CALLABLE EFloat operator+(EFloat f) const {
93  EFloat r;
94  r.v = v + f.v;
95 #ifdef NDEBUG
96  r.ld = ld + f.ld;
97 #endif
98  r.err = err + f.err;
99  r.err.low = Numbers::nextFloatDown(r.err.low);
100  r.err.high = Numbers::nextFloatUp(r.err.high);
101  return r;
102  }
103  HERMES_DEVICE_CALLABLE EFloat operator-(EFloat f) const {
104  EFloat r;
105  r.v = v - f.v;
106 #ifdef NDEBUG
107  r.ld = ld - f.ld;
108 #endif
109  r.err = err - f.err;
110  r.err.low = Numbers::nextFloatDown(r.err.low);
111  r.err.high = Numbers::nextFloatUp(r.err.high);
112  return r;
113  }
114  HERMES_DEVICE_CALLABLE EFloat operator*(EFloat f) const {
115  EFloat r;
116  r.v = v * f.v;
117 #ifdef NDEBUG
118  r.ld = ld * f.ld;
119 #endif
120  r.err = err * f.err;
121  r.err.low = Numbers::nextFloatDown(r.err.low);
122  r.err.high = Numbers::nextFloatUp(r.err.high);
123  return r;
124  }
125  HERMES_DEVICE_CALLABLE EFloat operator/(EFloat f) const {
126  EFloat r;
127  r.v = v / f.v;
128 #ifdef NDEBUG
129  r.ld = ld / f.ld;
130 #endif
131  r.err = err / f.err;
132  r.err.low = Numbers::nextFloatDown(r.err.low);
133  r.err.high = Numbers::nextFloatUp(r.err.high);
134  return r;
135  }
136  // boolean
137  HERMES_DEVICE_CALLABLE bool operator==(EFloat f) const { return v == f.v; }
138  // *******************************************************************************************************************
139  // METHODS
140  // *******************************************************************************************************************
143  [[nodiscard]] HERMES_DEVICE_CALLABLE f32 absoluteError() const { return err.high - err.low; }
146  [[nodiscard]] HERMES_DEVICE_CALLABLE f32 upperBound() const { return err.high; }
149  [[nodiscard]] HERMES_DEVICE_CALLABLE f32 lowerBound() const { return err.low; }
150 #ifdef NDEBUG
153  f64 relativeError() const;
156  long double preciseValue() const;
157 #endif
158  // *******************************************************************************************************************
159  // PUBLIC FIELDS
160  // *******************************************************************************************************************
161 private:
162  float v;
163  Interval<f32> err;
164 #ifdef NDEBUG
165  long double ld;
166 #endif
167 };
168 
169 }
170 
171 #endif //HERMES_HERMES_NUMERIC_E_FLOAT_H
172 
Represents a value with error bounds.
Definition: e_float.h:47
HERMES_DEVICE_CALLABLE f32 upperBound() const
Computes the upper error bound carried by this number.
Definition: e_float.h:146
HERMES_DEVICE_CALLABLE f32 lowerBound() const
Computes the lower error bound carried by this number.
Definition: e_float.h:149
HERMES_DEVICE_CALLABLE EFloat()
Default constructor.
Definition: e_float.h:64
HERMES_DEVICE_CALLABLE f32 absoluteError() const
Computes the absolute error carried by this number.
Definition: e_float.h:143
HERMES_DEVICE_CALLABLE EFloat(f32 v, f32 e=0.f)
Constructs from value and error size.
Definition: e_float.h:68
T low
lowest interval value
Definition: interval.h:163
T high
greatest interval value
Definition: interval.h:164
#define HERMES_DEVICE_CALLABLE
Specifies that the function can be called from both host and device sides.
Definition: defs.h:45
double f64
64 bit size floating point type
Definition: defs.h:79
float f32
32 bit size floating point type
Definition: defs.h:78
Numeric interval.
static HERMES_DEVICE_CALLABLE f32 nextFloatUp(f32 v)
Computes the next greater representable floating-point value.
Definition: numeric.h:392
static HERMES_DEVICE_CALLABLE f32 nextFloatDown(f32 v)
Computes the next smaller representable floating-point value.
Definition: numeric.h:411