Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
Numeric.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* Numeric.h (C) 2000-2020 */
9/* */
10/* Numeric constant definitions. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_DATATYPE_NUMERIC_H
13#define ARCANE_DATATYPE_NUMERIC_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/Limits.h"
18#include "arcane/utils/Math.h"
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29/*!
30 * \internal
31 * \brief Comparison operations for a numeric type T
32 *
33 * This class defines a comparison operator for the
34 * template parameter type 'T'. There are two types of comparisons:
35 * - exact comparisons (isEqual());
36 * - approximate comparisons (isNearlyEqual()).
37 *
38 * Both types of comparisons are identical, except for
39 * floating-point types or equivalents. In this case, the exact comparison
40 * compares the two values bit by bit, and the approximate comparison
41 * considers two numbers equal if their relative difference is
42 * less than an epsilon.
43 */
44template <class T>
46{
47 public:
48
49 /*!
50 * \brief Compares \a a to zero.
51 * \retval true if \a a is zero within an epsilon,
52 * \retval false otherwise.
53 */
54 constexpr ARCCORE_HOST_DEVICE static bool isNearlyZero(const T& a)
55 {
56 return (a == T());
57 }
58
59 /*!
60 * \brief Compares \a a to zero.
61 * \retval true if \a a is exactly zero,
62 * \retval false otherwise.
63 */
64 constexpr ARCCORE_HOST_DEVICE static bool isZero(const T& a)
65 {
66 return (a == T());
67 }
68
69 /*!
70 * \brief Compares \a a to \a b.
71 * \retval true if \a a and \b are equal within an epsilon,
72 * \retval false otherwise.
73 */
74 constexpr ARCCORE_HOST_DEVICE static bool isNearlyEqual(const T& a, const T& b)
75 {
76 return (a == b);
77 }
78
79 /*!
80 * \brief Compares \a a to \a b.
81 * \retval true if \a a and \b are equal within an epsilon,
82 * \retval false otherwise.
83 */
84 constexpr ARCCORE_HOST_DEVICE static bool isNearlyEqualWithEpsilon(const T& a, const T& b, const T&)
85 {
86 return (a == b);
87 }
88
89 /*!
90 * \brief Compares \a a to \a b.
91 * \retval true if \a a and \b are exactly equal,
92 * \retval false otherwise.
93 */
94 constexpr ARCCORE_HOST_DEVICE static bool isEqual(const T& a, const T& b)
95 {
96 return (a == b);
97 }
98};
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
103/*!
104 * \internal
105 * \brief Defines the == operator for floats.
106 *
107 * \note Eventually, it should use the 'numeric_limits' class
108 * from the STL when it is implemented.
109 */
110template <class T>
112{
113 private:
114
115 constexpr ARCCORE_HOST_DEVICE static T nepsilon() { return FloatInfo<T>::nearlyEpsilon(); }
116
117 public:
118
119 constexpr ARCCORE_HOST_DEVICE static bool isNearlyZero(T a)
120 {
121 return ((a < 0.) ? a > -nepsilon() : a < nepsilon());
122 }
123
124 /*!
125 * \brief Compares \a a to zero within \a epsilon.
126 *
127 * \a epsilon must be positive.
128 *
129 * \retval true if abs(a)<epilon
130 * \retval false otherwise
131 */
132 constexpr ARCCORE_HOST_DEVICE static bool isNearlyZeroWithEpsilon(T a, T epsilon)
133 {
134 return ((a < 0.) ? a > -epsilon : a < epsilon);
135 }
136
137 /*! \brief Compares \a with \a b*epsilon.
138 * \warning b must be positive. */
139 ARCCORE_HOST_DEVICE static bool isNearlyZero(T a, T b)
140 {
141 return ((a < 0.) ? a > -(b * nepsilon()) : a < (b * nepsilon()));
142 }
143
144 constexpr ARCCORE_HOST_DEVICE static bool isTrueZero(T a) { return (a == FloatInfo<T>::zero()); }
145 constexpr ARCCORE_HOST_DEVICE static bool isZero(T a) { return (a == FloatInfo<T>::zero()); }
146 constexpr ARCCORE_HOST_DEVICE static bool isNearlyEqual(T a, T b)
147 {
148 T s = math::abs(a) + math::abs(b);
149 T d = a - b;
150 return (d == FloatInfo<T>::zero()) ? true : isNearlyZero(d / s);
151 }
152 constexpr ARCCORE_HOST_DEVICE static bool isNearlyEqualWithEpsilon(T a, T b, T epsilon)
153 {
154 T s = math::abs(a) + math::abs(b);
155 T d = a - b;
156 return (d == FloatInfo<T>::zero()) ? true : isNearlyZeroWithEpsilon(d / s, epsilon);
157 }
158 constexpr ARCCORE_HOST_DEVICE static bool isEqual(T a, T b)
159 {
160 return a == b;
161 }
162};
163
164/*!
165 * \internal
166 * \brief Specialization of TypeEqualT for the <tt>float</tt> type.
167 */
168template <>
169class TypeEqualT<float>
170: public FloatEqualT<float>
171{};
172
173/*!
174 * \internal
175 * \brief Specialization of TypeEqualT for the <tt>double</tt> type.
176 */
177template <>
178class TypeEqualT<double>
179: public FloatEqualT<double>
180{};
181
182/*!
183 * \internal
184 * \brief Specialization of TypeEqualT for the <tt>long double</tt> type.
185 */
186template <>
187class TypeEqualT<long double>
188: public FloatEqualT<long double>
189{};
190
191#ifdef ARCANE_REAL_NOT_BUILTIN
192/*!
193 * \internal
194 * \brief Specialization of TypeEqualT for the <tt>Real</tt> type.
195 */
196template <>
197class TypeEqualT<Real>
198: public FloatEqualT<Real>
199{};
200#endif
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
205namespace math
206{
207
208 /*!
209 * \brief Tests if two values are approximately equal.
210 * For integer types, this function is equivalent to IsEqual().
211 * In the case of real types, the two numbers are considered equal
212 * if and only if the absolute value of their relative difference is
213 * less than a given epsilon. This
214 * epsilon is equal to float_info<_Type>::nearlyEpsilon().
215 * \retval true if the two values are equal,
216 * \retval false otherwise.
217 */
218 template <class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
219 isNearlyEqual(const _Type& a, const _Type& b)
220 {
222 }
223
224 //! Overload for reals
225 constexpr ARCCORE_HOST_DEVICE inline bool
227 {
229 }
230
231 /*!
232 * \brief Tests if two values are approximately equal.
233 * For integer types, this function is equivalent to IsEqual().
234 * In the case of real types, the two numbers are considered equal
235 * if and only if the absolute value of their relative difference is
236 * less than \a epsilon.
237 *
238 * \retval true if the two values are equal,
239 * \retval false otherwise.
240 */
241 template <class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
242 isNearlyEqualWithEpsilon(const _Type& a, const _Type& b, const _Type& epsilon)
243 {
245 }
246
247 //! Overload for reals
248 ARCCORE_HOST_DEVICE constexpr inline bool
250 {
251 return TypeEqualT<Real>::isNearlyEqualWithEpsilon(a, b, epsilon);
252 }
253
254 /*!
255 * \brief Tests the bit-by-bit equality between two values.
256 * \retval true if the two values are equal,
257 * \retval false otherwise.
258 */
259 template <class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
260 isEqual(const _Type& a, const _Type& b)
261 {
262 return TypeEqualT<_Type>::isEqual(a, b);
263 }
264
265 //! Overload for reals
266 ARCCORE_HOST_DEVICE constexpr inline bool
268 {
269 return TypeEqualT<Real>::isEqual(a, b);
270 }
271
272 /*!
273 * \brief Tests if a value is approximately equal to zero within an epsilon.
274 *
275 * For integer types, this function is equivalent to IsZero().
276 * In the case of real types, the value is considered equal to
277 * zero if and only if its absolute value is less than an epsilon
278 * given by the function float_info<_Type>::nearlyEpsilon().
279 * \retval true if the two values are equal,
280 * \retval false otherwise.
281 */
282 template <class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
283 isNearlyZeroWithEpsilon(const _Type& a, const _Type& epsilon)
284 {
286 }
287
288 /*!
289 * \brief Tests if a value is approximately equal to zero using the standard epsilon.
290 *
291 * The standard epsilon is the one returned by FloatInfo<_Type>::nearlyEpsilon().
292 *
293 * \sa isNearlyZero(const _Type& a,const _Type& epsilon).
294 */
295 template <class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
296 isNearlyZero(const _Type& a)
297 {
299 }
300
301 /*!
302 * \brief Tests if a value is exactly equal to zero.
303 * \retval true if \a is zero,
304 * \retval false otherwise.
305 */
306 template <class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
307 isZero(const _Type& a)
308 {
310 }
311} // namespace math
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
316} // End namespace Arcane
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
321#endif
constexpr __host__ static __device__ bool isNearlyZeroWithEpsilon(T a, T epsilon)
Compares a to zero within epsilon.
Definition Numeric.h:132
__host__ static __device__ bool isNearlyZero(T a, T b)
Compares with b*epsilon.
Definition Numeric.h:139
Information about the floating-point type.
Definition Limits.h:49
constexpr __host__ static __device__ bool isNearlyZero(const T &a)
Compares a to zero.
Definition Numeric.h:54
constexpr __host__ static __device__ bool isZero(const T &a)
Compares a to zero.
Definition Numeric.h:64
constexpr __host__ static __device__ bool isEqual(const T &a, const T &b)
Compares a to b.
Definition Numeric.h:94
constexpr __host__ static __device__ bool isNearlyEqual(const T &a, const T &b)
Compares a to b.
Definition Numeric.h:74
constexpr __host__ static __device__ bool isNearlyEqualWithEpsilon(const T &a, const T &b, const T &)
Compares a to b.
Definition Numeric.h:84
constexpr __host__ __device__ bool isNearlyZeroWithEpsilon(const _Type &a, const _Type &epsilon)
Tests if a value is approximately equal to zero within an epsilon.
Definition Numeric.h:283
constexpr __host__ __device__ bool isNearlyEqualWithEpsilon(const _Type &a, const _Type &b, const _Type &epsilon)
Tests if two values are approximately equal. For integer types, this function is equivalent to IsEqua...
Definition Numeric.h:242
constexpr __host__ __device__ bool isNearlyEqual(const _Type &a, const _Type &b)
Tests if two values are approximately equal. For integer types, this function is equivalent to IsEqua...
Definition Numeric.h:219
bool isZero(const BuiltInProxy< _Type > &a)
Tests if a value is exactly equal to zero.
constexpr __host__ __device__ bool isEqual(const _Type &a, const _Type &b)
Tests the bit-by-bit equality between two values.
Definition Numeric.h:260
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
double Real
Type representing a real number.