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