1 | // Copyright (C) 2019 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qnumeric.h" |
5 | #include "qnumeric_p.h" |
6 | #include <string.h> |
7 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | /*! |
11 | \headerfile <QtNumeric> |
12 | \inmodule QtCore |
13 | \title Qt Numeric Functions |
14 | |
15 | \brief The <QtNumeric> header file provides common numeric functions. |
16 | |
17 | The <QtNumeric> header file contains various numeric functions |
18 | for comparing and adjusting a numeric value. |
19 | */ |
20 | |
21 | /*! |
22 | Returns \c true if the double \a {d} is equivalent to infinity. |
23 | \relates <QtNumeric> |
24 | \sa qInf() |
25 | */ |
26 | Q_CORE_EXPORT bool qIsInf(double d) { return qt_is_inf(d); } |
27 | |
28 | /*! |
29 | Returns \c true if the double \a {d} is not a number (NaN). |
30 | \relates <QtNumeric> |
31 | */ |
32 | Q_CORE_EXPORT bool qIsNaN(double d) { return qt_is_nan(d); } |
33 | |
34 | /*! |
35 | Returns \c true if the double \a {d} is a finite number. |
36 | \relates <QtNumeric> |
37 | */ |
38 | Q_CORE_EXPORT bool qIsFinite(double d) { return qt_is_finite(d); } |
39 | |
40 | /*! |
41 | Returns \c true if the float \a {f} is equivalent to infinity. |
42 | \relates <QtNumeric> |
43 | \sa qInf() |
44 | */ |
45 | Q_CORE_EXPORT bool qIsInf(float f) { return qt_is_inf(f); } |
46 | |
47 | /*! |
48 | Returns \c true if the float \a {f} is not a number (NaN). |
49 | \relates <QtNumeric> |
50 | */ |
51 | Q_CORE_EXPORT bool qIsNaN(float f) { return qt_is_nan(f); } |
52 | |
53 | /*! |
54 | Returns \c true if the float \a {f} is a finite number. |
55 | \relates <QtNumeric> |
56 | */ |
57 | Q_CORE_EXPORT bool qIsFinite(float f) { return qt_is_finite(f); } |
58 | |
59 | #if QT_CONFIG(signaling_nan) |
60 | /*! |
61 | Returns the bit pattern of a signalling NaN as a double. |
62 | \relates <QtNumeric> |
63 | */ |
64 | Q_CORE_EXPORT double qSNaN() { return qt_snan(); } |
65 | #endif |
66 | |
67 | /*! |
68 | Returns the bit pattern of a quiet NaN as a double. |
69 | \relates <QtNumeric> |
70 | \sa qIsNaN() |
71 | */ |
72 | Q_CORE_EXPORT double qQNaN() { return qt_qnan(); } |
73 | |
74 | /*! |
75 | Returns the bit pattern for an infinite number as a double. |
76 | \relates <QtNumeric> |
77 | \sa qIsInf() |
78 | */ |
79 | Q_CORE_EXPORT double qInf() { return qt_inf(); } |
80 | |
81 | /*! |
82 | \fn int qFpClassify(double val) |
83 | \fn int qFpClassify(float val) |
84 | |
85 | \relates <QtNumeric> |
86 | Classifies a floating-point value. |
87 | |
88 | The return values are defined in \c{<cmath>}: returns one of the following, |
89 | determined by the floating-point class of \a val: |
90 | \list |
91 | \li FP_NAN not a number |
92 | \li FP_INFINITE infinities (positive or negative) |
93 | \li FP_ZERO zero (positive or negative) |
94 | \li FP_NORMAL finite with a full mantissa |
95 | \li FP_SUBNORMAL finite with a reduced mantissa |
96 | \endlist |
97 | */ |
98 | Q_CORE_EXPORT int qFpClassify(double val) { return qt_fpclassify(d: val); } |
99 | Q_CORE_EXPORT int qFpClassify(float val) { return qt_fpclassify(f: val); } |
100 | |
101 | |
102 | /*! |
103 | \internal |
104 | */ |
105 | static inline quint32 f2i(float f) |
106 | { |
107 | quint32 i; |
108 | memcpy(dest: &i, src: &f, n: sizeof(f)); |
109 | return i; |
110 | } |
111 | |
112 | /*! |
113 | Returns the number of representable floating-point numbers between \a a and \a b. |
114 | |
115 | This function provides an alternative way of doing approximated comparisons of floating-point |
116 | numbers similar to qFuzzyCompare(). However, it returns the distance between two numbers, which |
117 | gives the caller a possibility to choose the accepted error. Errors are relative, so for |
118 | instance the distance between 1.0E-5 and 1.00001E-5 will give 110, while the distance between |
119 | 1.0E36 and 1.00001E36 will give 127. |
120 | |
121 | This function is useful if a floating point comparison requires a certain precision. |
122 | Therefore, if \a a and \a b are equal it will return 0. The maximum value it will return for 32-bit |
123 | floating point numbers is 4,278,190,078. This is the distance between \c{-FLT_MAX} and |
124 | \c{+FLT_MAX}. |
125 | |
126 | The function does not give meaningful results if any of the arguments are \c Infinite or \c NaN. |
127 | You can check for this by calling qIsFinite(). |
128 | |
129 | The return value can be considered as the "error", so if you for instance want to compare |
130 | two 32-bit floating point numbers and all you need is an approximated 24-bit precision, you can |
131 | use this function like this: |
132 | |
133 | \snippet code/src_corelib_global_qnumeric.cpp 0 |
134 | |
135 | \sa qFuzzyCompare() |
136 | \since 5.2 |
137 | \relates <QtNumeric> |
138 | */ |
139 | Q_CORE_EXPORT quint32 qFloatDistance(float a, float b) |
140 | { |
141 | static const quint32 smallestPositiveFloatAsBits = 0x00000001; // denormalized, (SMALLEST), (1.4E-45) |
142 | /* Assumes: |
143 | * IEE754 format. |
144 | * Integers and floats have the same endian |
145 | */ |
146 | static_assert(sizeof(quint32) == sizeof(float)); |
147 | Q_ASSERT(qIsFinite(a) && qIsFinite(b)); |
148 | if (a == b) |
149 | return 0; |
150 | if ((a < 0) != (b < 0)) { |
151 | // if they have different signs |
152 | if (a < 0) |
153 | a = -a; |
154 | else /*if (b < 0)*/ |
155 | b = -b; |
156 | return qFloatDistance(a: 0.0F, b: a) + qFloatDistance(a: 0.0F, b); |
157 | } |
158 | if (a < 0) { |
159 | a = -a; |
160 | b = -b; |
161 | } |
162 | // at this point a and b should not be negative |
163 | |
164 | // 0 is special |
165 | if (!a) |
166 | return f2i(f: b) - smallestPositiveFloatAsBits + 1; |
167 | if (!b) |
168 | return f2i(f: a) - smallestPositiveFloatAsBits + 1; |
169 | |
170 | // finally do the common integer subtraction |
171 | return a > b ? f2i(f: a) - f2i(f: b) : f2i(f: b) - f2i(f: a); |
172 | } |
173 | |
174 | |
175 | /*! |
176 | \internal |
177 | */ |
178 | static inline quint64 d2i(double d) |
179 | { |
180 | quint64 i; |
181 | memcpy(dest: &i, src: &d, n: sizeof(d)); |
182 | return i; |
183 | } |
184 | |
185 | /*! |
186 | Returns the number of representable floating-point numbers between \a a and \a b. |
187 | |
188 | This function serves the same purpose as \c{qFloatDistance(float, float)}, but |
189 | returns the distance between two \c double numbers. Since the range is larger |
190 | than for two \c float numbers (\c{[-DBL_MAX,DBL_MAX]}), the return type is quint64. |
191 | |
192 | |
193 | \sa qFuzzyCompare() |
194 | \since 5.2 |
195 | \relates <QtNumeric> |
196 | */ |
197 | Q_CORE_EXPORT quint64 qFloatDistance(double a, double b) |
198 | { |
199 | static const quint64 smallestPositiveFloatAsBits = 0x1; // denormalized, (SMALLEST) |
200 | /* Assumes: |
201 | * IEE754 format double precision |
202 | * Integers and floats have the same endian |
203 | */ |
204 | static_assert(sizeof(quint64) == sizeof(double)); |
205 | Q_ASSERT(qIsFinite(a) && qIsFinite(b)); |
206 | if (a == b) |
207 | return 0; |
208 | if ((a < 0) != (b < 0)) { |
209 | // if they have different signs |
210 | if (a < 0) |
211 | a = -a; |
212 | else /*if (b < 0)*/ |
213 | b = -b; |
214 | return qFloatDistance(a: 0.0, b: a) + qFloatDistance(a: 0.0, b); |
215 | } |
216 | if (a < 0) { |
217 | a = -a; |
218 | b = -b; |
219 | } |
220 | // at this point a and b should not be negative |
221 | |
222 | // 0 is special |
223 | if (!a) |
224 | return d2i(d: b) - smallestPositiveFloatAsBits + 1; |
225 | if (!b) |
226 | return d2i(d: a) - smallestPositiveFloatAsBits + 1; |
227 | |
228 | // finally do the common integer subtraction |
229 | return a > b ? d2i(d: a) - d2i(d: b) : d2i(d: b) - d2i(d: a); |
230 | } |
231 | |
232 | /*! |
233 | \fn template<typename T> bool qAddOverflow(T v1, T v2, T *result) |
234 | \relates <QtNumeric> |
235 | \since 6.1 |
236 | |
237 | Adds two values \a v1 and \a v2, of a numeric type \c T and records the |
238 | value in \a result. If the addition overflows the valid range for type \c T, |
239 | returns \c true, otherwise returns \c false. |
240 | |
241 | An implementation is guaranteed to be available for 8-, 16-, and 32-bit |
242 | integer types, as well as integer types of the size of a pointer. Overflow |
243 | math for other types, if available, is considered private API. |
244 | */ |
245 | |
246 | /*! |
247 | \fn template <typename T, T V2> bool qAddOverflow(T v1, std::integral_constant<T, V2>, T *r) |
248 | \since 6.1 |
249 | \internal |
250 | |
251 | Equivalent to qAddOverflow(v1, v2, r) with \a v1 as first argument, the |
252 | compile time constant \c V2 as second argument, and \a r as third argument. |
253 | */ |
254 | |
255 | /*! |
256 | \fn template <auto V2, typename T> bool qAddOverflow(T v1, T *r) |
257 | \since 6.1 |
258 | \internal |
259 | |
260 | Equivalent to qAddOverflow(v1, v2, r) with \a v1 as first argument, the |
261 | compile time constant \c V2 as second argument, and \a r as third argument. |
262 | */ |
263 | |
264 | /*! |
265 | \fn template<typename T> bool qSubOverflow(T v1, T v2, T *result) |
266 | \relates <QtNumeric> |
267 | \since 6.1 |
268 | |
269 | Subtracts \a v2 from \a v1 and records the resulting value in \a result. If |
270 | the subtraction overflows the valid range for type \c T, returns \c true, |
271 | otherwise returns \c false. |
272 | |
273 | An implementation is guaranteed to be available for 8-, 16-, and 32-bit |
274 | integer types, as well as integer types of the size of a pointer. Overflow |
275 | math for other types, if available, is considered private API. |
276 | */ |
277 | |
278 | /*! |
279 | \fn template <typename T, T V2> bool qSubOverflow(T v1, std::integral_constant<T, V2>, T *r) |
280 | \since 6.1 |
281 | \internal |
282 | |
283 | Equivalent to qSubOverflow(v1, v2, r) with \a v1 as first argument, the |
284 | compile time constant \c V2 as second argument, and \a r as third argument. |
285 | */ |
286 | |
287 | /*! |
288 | \fn template <auto V2, typename T> bool qSubOverflow(T v1, T *r) |
289 | \since 6.1 |
290 | \internal |
291 | |
292 | Equivalent to qSubOverflow(v1, v2, r) with \a v1 as first argument, the |
293 | compile time constant \c V2 as second argument, and \a r as third argument. |
294 | */ |
295 | |
296 | /*! |
297 | \fn template<typename T> bool qMulOverflow(T v1, T v2, T *result) |
298 | \relates <QtNumeric> |
299 | \since 6.1 |
300 | |
301 | Multiplies \a v1 and \a v2, and records the resulting value in \a result. If |
302 | the multiplication overflows the valid range for type \c T, returns |
303 | \c true, otherwise returns \c false. |
304 | |
305 | An implementation is guaranteed to be available for 8-, 16-, and 32-bit |
306 | integer types, as well as integer types of the size of a pointer. Overflow |
307 | math for other types, if available, is considered private API. |
308 | */ |
309 | |
310 | /*! |
311 | \fn template <typename T, T V2> bool qMulOverflow(T v1, std::integral_constant<T, V2>, T *r) |
312 | \since 6.1 |
313 | \internal |
314 | |
315 | Equivalent to qMulOverflow(v1, v2, r) with \a v1 as first argument, the |
316 | compile time constant \c V2 as second argument, and \a r as third argument. |
317 | This can be faster than calling the version with only variable arguments. |
318 | */ |
319 | |
320 | /*! |
321 | \fn template <auto V2, typename T> bool qMulOverflow(T v1, T *r) |
322 | \since 6.1 |
323 | \internal |
324 | |
325 | Equivalent to qMulOverflow(v1, v2, r) with \a v1 as first argument, the |
326 | compile time constant \c V2 as second argument, and \a r as third argument. |
327 | This can be faster than calling the version with only variable arguments. |
328 | */ |
329 | |
330 | /*! \fn template <typename T> T qAbs(const T &t) |
331 | \relates <QtNumeric> |
332 | |
333 | Compares \a t to the 0 of type T and returns the absolute |
334 | value. Thus if T is \e {double}, then \a t is compared to |
335 | \e{(double) 0}. |
336 | |
337 | Example: |
338 | |
339 | \snippet code/src_corelib_global_qglobal.cpp 10 |
340 | */ |
341 | |
342 | /*! \fn int qRound(double d) |
343 | \relates <QtNumeric> |
344 | |
345 | Rounds \a d to the nearest integer. |
346 | |
347 | Rounds half away from zero (e.g. 0.5 -> 1, -0.5 -> -1). |
348 | |
349 | \note This function does not guarantee correctness for high precisions. |
350 | |
351 | Example: |
352 | |
353 | \snippet code/src_corelib_global_qglobal.cpp 11A |
354 | |
355 | \note If the value \a d is outside the range of \c int, |
356 | the behavior is undefined. |
357 | */ |
358 | |
359 | /*! \fn int qRound(float d) |
360 | \relates <QtNumeric> |
361 | |
362 | Rounds \a d to the nearest integer. |
363 | |
364 | Rounds half away from zero (e.g. 0.5f -> 1, -0.5f -> -1). |
365 | |
366 | \note This function does not guarantee correctness for high precisions. |
367 | |
368 | Example: |
369 | |
370 | \snippet code/src_corelib_global_qglobal.cpp 11B |
371 | |
372 | \note If the value \a d is outside the range of \c int, |
373 | the behavior is undefined. |
374 | */ |
375 | |
376 | /*! \fn qint64 qRound64(double d) |
377 | \relates <QtNumeric> |
378 | |
379 | Rounds \a d to the nearest 64-bit integer. |
380 | |
381 | Rounds half away from zero (e.g. 0.5 -> 1, -0.5 -> -1). |
382 | |
383 | \note This function does not guarantee correctness for high precisions. |
384 | |
385 | Example: |
386 | |
387 | \snippet code/src_corelib_global_qglobal.cpp 12A |
388 | |
389 | \note If the value \a d is outside the range of \c qint64, |
390 | the behavior is undefined. |
391 | */ |
392 | |
393 | /*! \fn qint64 qRound64(float d) |
394 | \relates <QtNumeric> |
395 | |
396 | Rounds \a d to the nearest 64-bit integer. |
397 | |
398 | Rounds half away from zero (e.g. 0.5f -> 1, -0.5f -> -1). |
399 | |
400 | \note This function does not guarantee correctness for high precisions. |
401 | |
402 | Example: |
403 | |
404 | \snippet code/src_corelib_global_qglobal.cpp 12B |
405 | |
406 | \note If the value \a d is outside the range of \c qint64, |
407 | the behavior is undefined. |
408 | */ |
409 | |
410 | /*! |
411 | \fn bool qFuzzyCompare(double p1, double p2) |
412 | \relates <QtNumeric> |
413 | \since 4.4 |
414 | \threadsafe |
415 | |
416 | Compares the floating point value \a p1 and \a p2 and |
417 | returns \c true if they are considered equal, otherwise \c false. |
418 | |
419 | Note that comparing values where either \a p1 or \a p2 is 0.0 will not work, |
420 | nor does comparing values where one of the values is NaN or infinity. |
421 | If one of the values is always 0.0, use qFuzzyIsNull instead. If one of the |
422 | values is likely to be 0.0, one solution is to add 1.0 to both values. |
423 | |
424 | \snippet code/src_corelib_global_qglobal.cpp 46 |
425 | |
426 | The two numbers are compared in a relative way, where the |
427 | exactness is stronger the smaller the numbers are. |
428 | */ |
429 | |
430 | /*! |
431 | \fn bool qFuzzyCompare(float p1, float p2) |
432 | \relates <QtNumeric> |
433 | \since 4.4 |
434 | \threadsafe |
435 | |
436 | Compares the floating point value \a p1 and \a p2 and |
437 | returns \c true if they are considered equal, otherwise \c false. |
438 | |
439 | The two numbers are compared in a relative way, where the |
440 | exactness is stronger the smaller the numbers are. |
441 | */ |
442 | |
443 | /*! |
444 | \fn bool qFuzzyIsNull(double d) |
445 | \relates <QtNumeric> |
446 | \since 4.4 |
447 | \threadsafe |
448 | |
449 | Returns true if the absolute value of \a d is within 0.000000000001 of 0.0. |
450 | */ |
451 | |
452 | /*! |
453 | \fn bool qFuzzyIsNull(float f) |
454 | \relates <QtNumeric> |
455 | \since 4.4 |
456 | \threadsafe |
457 | |
458 | Returns true if the absolute value of \a f is within 0.00001f of 0.0. |
459 | */ |
460 | |
461 | namespace QtNumericTests { |
462 | |
463 | template <typename T> static constexpr T max = std::numeric_limits<T>::max(); |
464 | template <typename T> static constexpr T min = std::numeric_limits<T>::min(); |
465 | |
466 | static_assert(qt_saturate<short>(x: max<unsigned>) == max<short>); |
467 | static_assert(qt_saturate<int>(x: max<unsigned>) == max<int>); |
468 | static_assert(qt_saturate<qint64>(x: max<unsigned>) == qint64(max<unsigned>)); |
469 | |
470 | static_assert(qt_saturate<short>(x: max<int>) == max<short>); |
471 | static_assert(qt_saturate<unsigned>(x: max<int>) == unsigned(max<int>)); |
472 | static_assert(qt_saturate<qint64>(x: max<int>) == qint64(max<int>)); |
473 | |
474 | static_assert(qt_saturate<short>(x: max<qint64>) == max<short>); |
475 | static_assert(qt_saturate<int>(x: max<qint64>) == max<int>); |
476 | static_assert(qt_saturate<unsigned>(x: max<qint64>) == max<unsigned>); |
477 | static_assert(qt_saturate<quint64>(x: max<qint64>) == quint64(max<qint64>)); |
478 | |
479 | static_assert(qt_saturate<short>(x: max<quint64>) == max<short>); |
480 | static_assert(qt_saturate<int>(x: max<quint64>) == max<int>); |
481 | static_assert(qt_saturate<unsigned>(x: max<quint64>) == max<unsigned>); |
482 | static_assert(qt_saturate<qint64>(x: max<quint64>) == max<qint64>); |
483 | |
484 | static_assert(qt_saturate<short>(x: min<int>) == min<short>); |
485 | static_assert(qt_saturate<qint64>(x: min<int>) == qint64(min<int>)); |
486 | static_assert(qt_saturate<unsigned>(x: min<int>) == 0); |
487 | static_assert(qt_saturate<quint64>(x: min<int>) == 0); |
488 | |
489 | static_assert(qt_saturate<short>(x: min<qint64>) == min<short>); |
490 | static_assert(qt_saturate<int>(x: min<qint64>) == min<int>); |
491 | static_assert(qt_saturate<unsigned>(x: min<qint64>) == 0); |
492 | static_assert(qt_saturate<quint64>(x: min<qint64>) == 0); |
493 | |
494 | } // namespace QtNumericTests |
495 | |
496 | QT_END_NAMESPACE |
497 | |