C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
real_type.hpp
Go to the documentation of this file.
1/*
2 **************************************************************
3 * C++ Mathematical Expression Toolkit Library *
4 * *
5 * Simple Real Type Example *
6 * Authors: Arash Partow (1999-2024) *
7 * URL: https://www.partow.net/programming/exprtk/index.html *
8 * *
9 * Copyright notice: *
10 * Free use of the Mathematical Expression Toolkit Library is *
11 * permitted under the guidelines and in accordance with the *
12 * most current version of the MIT License. *
13 * https://www.opensource.org/licenses/MIT *
14 * SPDX-License-Identifier: MIT *
15 * *
16 **************************************************************
17*/
18
19
20#ifndef INCLUDE_REAL_TYPE_HPP
21#define INCLUDE_REAL_TYPE_HPP
22
23
24#include <cmath>
25#include <algorithm>
26#include <limits>
27
28
29namespace real
30{
31 struct type
32 {
34 : d_(0.0)
35 {}
36
37 type(const type& d)
38 : d_(d.d_)
39 {}
40
41 type(const double& d)
42 : d_(d)
43 {}
44
45 template <typename T>
46 explicit type(const T& d)
47 : d_(static_cast<double>(d))
48 {}
49
50 type& operator=(const double &d) { d_ = d; return *this; }
51
52 template <typename T>
53 type& operator=(const T d) { d_ = static_cast<double>(d); return *this; }
54
55 inline type& operator =(const type& r) { d_ = r.d_; return *this; }
56 inline type& operator +=(const type& r) { d_ += r.d_; return *this; }
57 inline type& operator -=(const type& r) { d_ -= r.d_; return *this; }
58 inline type& operator *=(const type& r) { d_ *= r.d_; return *this; }
59 inline type& operator /=(const type& r) { d_ /= r.d_; return *this; }
60
61 inline type& operator =(const double r) { d_ = r; return *this; }
62 inline type& operator +=(const double r) { d_ += r; return *this; }
63 inline type& operator -=(const double r) { d_ -= r; return *this; }
64 inline type& operator *=(const double r) { d_ *= r; return *this; }
65 inline type& operator /=(const double r) { d_ /= r; return *this; }
66
67 inline type& operator++() { d_ += 1.0; return *this; }
68 inline type& operator--() { d_ -= 1.0; return *this; }
69
70 inline type operator++(int) { type tmp(d_); d_ += 1.0; return tmp; }
71 inline type operator--(int) { type tmp(d_); d_ -= 1.0; return tmp; }
72
73 inline type operator-() const { type d; d.d_ = -d_; return d; }
74
75 template <typename T>
76 inline operator T() const { return static_cast<T>(d_); }
77 inline operator bool() const { return (d_ != 0.0); }
78
79 inline bool operator ==(const type& r) const { return (d_ == r.d_); }
80 inline bool operator !=(const type& r) const { return (d_ != r.d_); }
81
82 double d_;
83 };
84
85 inline type operator+(const type r0, const type r1) { return type(r0.d_ + r1.d_); }
86 inline type operator-(const type r0, const type r1) { return type(r0.d_ - r1.d_); }
87 inline type operator*(const type r0, const type r1) { return type(r0.d_ * r1.d_); }
88 inline type operator/(const type r0, const type r1) { return type(r0.d_ / r1.d_); }
89
90 inline bool operator< (const type r0, const type r1) { return (r0.d_ < r1.d_); }
91 inline bool operator> (const type r0, const type r1) { return (r0.d_ > r1.d_); }
92 inline bool operator<=(const type r0, const type r1) { return (r0.d_ <= r1.d_); }
93 inline bool operator>=(const type r0, const type r1) { return (r0.d_ >= r1.d_); }
94
95 #define real_define_inequalities(Type) \
96 inline type operator+ (const Type/*&*/ r0, const type/*&*/ r1) { return type(r0 + r1.d_); } \
97 inline type operator- (const Type/*&*/ r0, const type/*&*/ r1) { return type(r0 - r1.d_); } \
98 inline type operator* (const Type/*&*/ r0, const type/*&*/ r1) { return type(r0 * r1.d_); } \
99 inline type operator/ (const Type/*&*/ r0, const type/*&*/ r1) { return type(r0 / r1.d_); } \
100 inline bool operator< (const Type/*&*/ r0, const type/*&*/ r1) { return (r0 < r1.d_); } \
101 inline bool operator> (const Type/*&*/ r0, const type/*&*/ r1) { return (r0 > r1.d_); } \
102 inline bool operator<=(const Type/*&*/ r0, const type/*&*/ r1) { return (r0 <= r1.d_); } \
103 inline bool operator>=(const Type/*&*/ r0, const type/*&*/ r1) { return (r0 >= r1.d_); } \
104 inline bool operator==(const Type/*&*/ r0, const type/*&*/ r1) { return (r0 == r1.d_); } \
105 inline bool operator!=(const Type/*&*/ r0, const type/*&*/ r1) { return (r0 != r1.d_); } \
106 inline type operator+ (const type/*&*/ r0, const Type/*&*/ r1) { return type(r0.d_ + r1); } \
107 inline type operator- (const type/*&*/ r0, const Type/*&*/ r1) { return type(r0.d_ - r1); } \
108 inline type operator* (const type/*&*/ r0, const Type/*&*/ r1) { return type(r0.d_ * r1); } \
109 inline type operator/ (const type/*&*/ r0, const Type/*&*/ r1) { return type(r0.d_ / r1); } \
110 inline bool operator< (const type/*&*/ r0, const Type/*&*/ r1) { return (r0.d_ < r1); } \
111 inline bool operator> (const type/*&*/ r0, const Type/*&*/ r1) { return (r0.d_ > r1); } \
112 inline bool operator<=(const type/*&*/ r0, const Type/*&*/ r1) { return (r0.d_ <= r1); } \
113 inline bool operator>=(const type/*&*/ r0, const Type/*&*/ r1) { return (r0.d_ >= r1); } \
114 inline bool operator==(const type/*&*/ r0, const Type/*&*/ r1) { return (r0.d_ == r1); } \
115 inline bool operator!=(const type/*&*/ r0, const Type/*&*/ r1) { return (r0.d_ != r1); } \
116
122 real_define_inequalities(unsigned long long)
123 real_define_inequalities(unsigned long int )
124}
125
126namespace std
127{
128 template <>
129 class numeric_limits<real::type>
130 {
132
133 public:
134
135 static const bool is_specialized = true;
136 static number_type (min) () { return std::numeric_limits<double>::min(); }
137 static number_type (max) () { return std::numeric_limits<double>::max(); }
138 static number_type lowest() { return -(max)(); }
139 static number_type epsilon() { return std::numeric_limits<double>::epsilon(); }
140 static number_type round_error() { return std::numeric_limits<double>::round_error(); }
141 static number_type infinity() { return std::numeric_limits<double>::infinity(); }
142 static number_type quiet_NaN() { return std::numeric_limits<double>::quiet_NaN(); }
143 static number_type signaling_NaN() { return std::numeric_limits<double>::signaling_NaN(); }
144 static number_type denorm_min() { return std::numeric_limits<double>::denorm_min(); }
145 static const int digits = std::numeric_limits<double>::digits;
146 static const int digits10 = std::numeric_limits<double>::digits10;
147 static const int radix = std::numeric_limits<double>::radix;
148 static const int min_exponent = std::numeric_limits<double>::min_exponent;
149 static const int min_exponent10 = std::numeric_limits<double>::min_exponent10;
150 static const int max_exponent = std::numeric_limits<double>::max_exponent;
151 static const int max_exponent10 = std::numeric_limits<double>::max_exponent10;
152 static const bool has_infinity = std::numeric_limits<double>::has_infinity;
153 static const bool has_quiet_NaN = std::numeric_limits<double>::has_quiet_NaN;
154 static const bool has_signaling_NaN = std::numeric_limits<double>::has_signaling_NaN;
155 static const bool has_denorm_loss = std::numeric_limits<double>::has_denorm_loss;
156 static const bool is_signed = std::numeric_limits<double>::is_signed;
157 static const bool is_integer = std::numeric_limits<double>::is_integer;
158 static const bool is_exact = std::numeric_limits<double>::is_exact;
159 static const bool is_iec559 = std::numeric_limits<double>::is_iec559;
160 static const bool is_bounded = std::numeric_limits<double>::is_bounded;
161 static const bool is_modulo = std::numeric_limits<double>::is_modulo;
162 static const bool traps = std::numeric_limits<double>::traps;
163 static const float_denorm_style has_denorm = std::numeric_limits<double>::has_denorm;
164 static const float_round_style round_style = std::numeric_limits<double>::round_style;
165 };
166}
167
168namespace real
169{
170 namespace details
171 {
172 namespace constant
173 {
174 static const double e = 2.71828182845904523536028747135266249775724709369996;
175 static const double pi = 3.14159265358979323846264338327950288419716939937510;
176 static const double pi_2 = 1.57079632679489661923132169163975144209858469968755;
177 static const double pi_4 = 0.78539816339744830961566084581987572104929234984378;
178 static const double pi_180 = 0.01745329251994329576923690768488612713442871888542;
179 static const double _1_pi = 0.31830988618379067153776752674502872406891929148091;
180 static const double _2_pi = 0.63661977236758134307553505349005744813783858296183;
181 static const double _180_pi = 57.29577951308232087679815481410517033240547246656443;
182 static const double log2 = 0.69314718055994530941723212145817656807550013436026;
183 static const double sqrt2 = 1.41421356237309504880168872420969807856967187537695;
184 }
185 }
186
187 inline type abs(const type v) { return std::abs (v.d_); }
188 inline type acos(const type v) { return std::acos (v.d_); }
189 inline type acosh(const type v) { return std::acosh(v.d_); }
190 inline type asin(const type v) { return std::asin (v.d_); }
191 inline type asinh(const type v) { return std::asinh(v.d_); }
192 inline type atan(const type v) { return std::atan (v.d_); }
193 inline type atanh(const type v) { return std::atanh(v.d_); }
194 inline type ceil(const type v) { return std::ceil (v.d_); }
195 inline type cos(const type v) { return std::cos (v.d_); }
196 inline type cosh(const type v) { return std::cosh (v.d_); }
197 inline type exp(const type v) { return std::exp (v.d_); }
198 inline type floor(const type v) { return std::floor(v.d_); }
199 inline type log(const type v) { return std::log (v.d_); }
200 inline type log10(const type v) { return std::log10(v.d_); }
201 inline type log2(const type v) { return std::log(v.d_) / type(real::details::constant::log2); }
202 inline type neg(const type v) { return type(-1.0) * v; }
203 inline type pos(const type v) { return v; }
204 inline type sin(const type v) { return std::sin (v.d_); }
205 inline type sinh(const type v) { return std::sinh (v.d_); }
206 inline type sqrt(const type v) { return std::sqrt (v.d_); }
207 inline type tan(const type v) { return std::tan (v.d_); }
208 inline type tanh(const type v) { return std::tanh (v.d_); }
209 inline type cot(const type v) { return type(1) / std::tan(v.d_); }
210 inline type sec(const type v) { return type(1) / std::cos(v.d_); }
211 inline type csc(const type v) { return type(1) / std::sin(v.d_); }
212 inline type r2d(const type v) { return (v.d_ * type(real::details::constant::_180_pi)); }
213 inline type d2r(const type v) { return (v.d_ * type(real::details::constant::pi_180)); }
214 inline type d2g(const type v) { return (v.d_ * type(10.0/9.0)); }
215 inline type g2d(const type v) { return (v.d_ * type(9.0/10.0)); }
216 inline type notl(const type v) { return (v != type(0) ? type(0) : type(1)); }
217 inline type frac(const type v) { return (v.d_ - static_cast<long long>(v.d_)); }
218 inline type trunc(const type v) { return type(static_cast<double>(static_cast<long long>(v.d_))); }
219
220 inline type modulus(const type v0, const type v1) { return std::fmod(v0.d_,v1.d_); }
221 inline type pow(const type v0, const type v1) { return std::pow(v0.d_,v1.d_); }
222 inline type logn(const type v0, const type v1) { return std::log(v0.d_) / std::log(v1.d_); }
223 inline type root(const type v0, const type v1) { return pow(v0,type(1.0) / v1); }
224 inline type atan2(const type v0, const type v1) { return std::atan2(v0.d_,v1.d_); }
225 inline type max(const type v0, const type v1) { return std::max(v0.d_,v1.d_); }
226 inline type min(const type v0, const type v1) { return std::min(v0.d_,v1.d_); }
227
228 inline bool is_true (const type v) { return (v != type(0)); }
229 inline bool is_false (const type v) { return (v == type(0)); }
230
231 inline type equal(const type v0x, const type v1x)
232 {
233 const type v0 = v0x.d_;
234 const type v1 = v1x.d_;
235 static const type epsilon = type(0.0000000001);
236 return (abs(v0 - v1) <= (max(type(1),max(abs(v0),abs(v1))) * epsilon)) ? type(1) : type(0);
237 }
238
239 inline type expm1(const type vx)
240 {
241 const type v = vx.d_;
242 if (abs(v) < type(0.00001))
243 return type(v + (0.5 * v * v));
244 else
245 return type(exp(v) - type(1));
246 }
247
248 inline type nequal(const type v0, const type v1)
249 {
250 static const type epsilon = type(0.0000000001);
251 return (abs(v0 - v1) > (max(type(1),max(abs(v0),abs(v1))) * epsilon)) ? type(1) : type(0);
252 }
253
254 inline type log1p(const type v)
255 {
256 if (v > type(-1))
257 {
258 if (abs(v) > type(0.0001))
259 {
260 return log(type(1) + v);
261 }
262 else
263 return (type(-0.5) * v + type(1)) * v;
264 }
265 else
266 return type(std::numeric_limits<double>::quiet_NaN());
267 }
268
269 inline type round(const type v)
270 {
271 return ((v < type(0)) ? ceil(v - type(0.5)) : floor(v + type(0.5)));
272 }
273
274 inline type roundn(const type v0, const type v1)
275 {
276 const type p10 = pow(type(10),trunc(v1));
277 if (v0 < type(0))
278 return type(ceil ((v0 * p10) - type(0.5)) / p10);
279 else
280 return type(floor((v0 * p10) + type(0.5)) / p10);
281 }
282
283 inline type hypot(const type v0, const type v1)
284 {
285 return sqrt((v0 * v0) + (v1 * v1));
286 }
287
288 inline type shr(const type v0, const type v1)
289 {
290 return v0 * (type(1) / pow(type(2),trunc(v1)));
291 }
292
293 inline type shl(const type v0, const type v1)
294 {
295 return v0 * pow(type(2),trunc(v1));
296 }
297
298 inline type sgn(const type v)
299 {
300 if (v > type(0)) return type(+1);
301 else if (v < type(0)) return type(-1);
302 else return type( 0);
303 }
304
305 inline type nand(const type v0, const type& v1)
306 {
307 return (is_false(v0) || is_false(v1)) ? type(1) : type(0);
308 }
309
310 inline type nor(const type v0, const type& v1)
311 {
312 return (is_false(v0) && is_false(v1)) ? type(1) : type(0);
313 }
314
315 inline type xnor(const type v0, const type& v1)
316 {
317 const bool v0_true = is_true(v0);
318 const bool v1_true = is_true(v1);
319 if ((v0_true && v1_true) || (!v0_true && !v1_true))
320 return type(1);
321 else
322 return type(0);
323 }
324
325 inline type erf(type v)
326 {
327 #if defined(_MSC_VER) && (_MSC_VER < 1900)
328 const type t = type(1) / (type(1) + type(0.5) * abs(v));
329
330 static const type c[] = {
331 type( 1.26551223), type(1.00002368),
332 type( 0.37409196), type(0.09678418),
333 type(-0.18628806), type(0.27886807),
334 type(-1.13520398), type(1.48851587),
335 type(-0.82215223), type(0.17087277)
336 };
337
338 type result = type(1) - t * exp((-v * v) -
339 c[0] + t * (c[1] + t *
340 (c[2] + t * (c[3] + t *
341 (c[4] + t * (c[5] + t *
342 (c[6] + t * (c[7] + t *
343 (c[8] + t * (c[9]))))))))));
344
345 return (v >= type(0)) ? result : -result;
346 #else
347 return ::erf(static_cast<double>(v));
348 #endif
349 }
350
351 inline type erfc(type v)
352 {
353 return type(1) - erf(v);
354 }
355}
356
357#endif
static number_type denorm_min()
static number_type infinity()
static number_type round_error()
static number_type quiet_NaN()
static number_type signaling_NaN()
static const double log2
static const double pi_2
static const double pi
static const double _1_pi
static const double _2_pi
static const double _180_pi
static const double pi_4
static const double sqrt2
static const double e
static const double pi_180
type sin(const type v)
type cot(const type v)
type r2d(const type v)
type pow(const type v0, const type v1)
type log1p(const type v)
type root(const type v0, const type v1)
type acos(const type v)
type erfc(type v)
type d2r(const type v)
type nor(const type v0, const type &v1)
type notl(const type v)
bool operator>=(const type r0, const type r1)
Definition real_type.hpp:93
type round(const type v)
bool operator<(const type r0, const type r1)
Definition real_type.hpp:90
type floor(const type v)
type modulus(const type v0, const type v1)
type cosh(const type v)
type erf(type v)
type nequal(const type v0, const type v1)
type log10(const type v)
bool is_false(const type v)
type acosh(const type v)
type csc(const type v)
bool operator<=(const type r0, const type r1)
Definition real_type.hpp:92
type cos(const type v)
type sinh(const type v)
type exp(const type v)
type frac(const type v)
type atan2(const type v0, const type v1)
type operator*(const type r0, const type r1)
Definition real_type.hpp:87
type trunc(const type v)
type shr(const type v0, const type v1)
type max(const type v0, const type v1)
type log2(const type v)
type asinh(const type v)
type operator/(const type r0, const type r1)
Definition real_type.hpp:88
type neg(const type v)
type logn(const type v0, const type v1)
type xnor(const type v0, const type &v1)
type nand(const type v0, const type &v1)
type tan(const type v)
type roundn(const type v0, const type v1)
type asin(const type v)
type g2d(const type v)
type ceil(const type v)
type atan(const type v)
type sgn(const type v)
type d2g(const type v)
type equal(const type v0x, const type v1x)
type abs(const type v)
type operator+(const type r0, const type r1)
Definition real_type.hpp:85
type operator-(const type r0, const type r1)
Definition real_type.hpp:86
type log(const type v)
type atanh(const type v)
type sqrt(const type v)
type sec(const type v)
type expm1(const type vx)
type shl(const type v0, const type v1)
type pos(const type v)
type tanh(const type v)
type hypot(const type v0, const type v1)
bool operator>(const type r0, const type r1)
Definition real_type.hpp:91
type min(const type v0, const type v1)
#define real_define_inequalities(Type)
Definition real_type.hpp:95
type(const double &d)
Definition real_type.hpp:41
type & operator*=(const type &r)
Definition real_type.hpp:58
type(const T &d)
Definition real_type.hpp:46
type & operator--()
Definition real_type.hpp:68
type & operator+=(const type &r)
Definition real_type.hpp:56
type & operator/=(const type &r)
Definition real_type.hpp:59
bool operator==(const type &r) const
Definition real_type.hpp:79
type operator-() const
Definition real_type.hpp:73
type & operator++()
Definition real_type.hpp:67
type(const type &d)
Definition real_type.hpp:37
bool operator!=(const type &r) const
Definition real_type.hpp:80
type & operator-=(const type &r)
Definition real_type.hpp:57
double d_
Definition real_type.hpp:82
type operator++(int)
Definition real_type.hpp:70
type operator--(int)
Definition real_type.hpp:71
type & operator=(const T d)
Definition real_type.hpp:53
type & operator=(const double &d)
Definition real_type.hpp:50