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
8QT_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*/
26Q_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*/
32Q_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*/
38Q_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*/
45Q_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*/
51Q_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*/
57Q_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*/
64Q_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*/
72Q_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*/
79Q_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*/
98Q_CORE_EXPORT int qFpClassify(double val) { return qt_fpclassify(d: val); }
99Q_CORE_EXPORT int qFpClassify(float val) { return qt_fpclassify(f: val); }
100
101
102/*!
103 \internal
104 */
105static 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*/
139Q_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 */
178static 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*/
197Q_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
461namespace QtNumericTests {
462
463template <typename T> static constexpr T max = std::numeric_limits<T>::max();
464template <typename T> static constexpr T min = std::numeric_limits<T>::min();
465
466static_assert(qt_saturate<short>(x: max<unsigned>) == max<short>);
467static_assert(qt_saturate<int>(x: max<unsigned>) == max<int>);
468static_assert(qt_saturate<qint64>(x: max<unsigned>) == qint64(max<unsigned>));
469
470static_assert(qt_saturate<short>(x: max<int>) == max<short>);
471static_assert(qt_saturate<unsigned>(x: max<int>) == unsigned(max<int>));
472static_assert(qt_saturate<qint64>(x: max<int>) == qint64(max<int>));
473
474static_assert(qt_saturate<short>(x: max<qint64>) == max<short>);
475static_assert(qt_saturate<int>(x: max<qint64>) == max<int>);
476static_assert(qt_saturate<unsigned>(x: max<qint64>) == max<unsigned>);
477static_assert(qt_saturate<quint64>(x: max<qint64>) == quint64(max<qint64>));
478
479static_assert(qt_saturate<short>(x: max<quint64>) == max<short>);
480static_assert(qt_saturate<int>(x: max<quint64>) == max<int>);
481static_assert(qt_saturate<unsigned>(x: max<quint64>) == max<unsigned>);
482static_assert(qt_saturate<qint64>(x: max<quint64>) == max<qint64>);
483
484static_assert(qt_saturate<short>(x: min<int>) == min<short>);
485static_assert(qt_saturate<qint64>(x: min<int>) == qint64(min<int>));
486static_assert(qt_saturate<unsigned>(x: min<int>) == 0);
487static_assert(qt_saturate<quint64>(x: min<int>) == 0);
488
489static_assert(qt_saturate<short>(x: min<qint64>) == min<short>);
490static_assert(qt_saturate<int>(x: min<qint64>) == min<int>);
491static_assert(qt_saturate<unsigned>(x: min<qint64>) == 0);
492static_assert(qt_saturate<quint64>(x: min<qint64>) == 0);
493
494} // namespace QtNumericTests
495
496QT_END_NAMESPACE
497

source code of qtbase/src/corelib/global/qnumeric.cpp