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

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