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 \note If \c {T} is a \e {signed integral} type, and \a t has the value
345 of \c {std::numeric_limits<T>::min()}, the behavior is undefined.
346*/
347
348/*! \fn int qRound(double d)
349 \relates <QtNumeric>
350
351 Rounds \a d to the nearest integer.
352
353 Rounds half away from zero (e.g. 0.5 -> 1, -0.5 -> -1).
354
355 \note This function does not guarantee correctness for high precisions.
356
357 Example:
358
359 \snippet code/src_corelib_global_qglobal.cpp 11A
360
361 \note If the value \a d is outside the range of \c int,
362 the behavior is undefined.
363*/
364
365/*! \fn int qRound(float d)
366 \relates <QtNumeric>
367
368 Rounds \a d to the nearest integer.
369
370 Rounds half away from zero (e.g. 0.5f -> 1, -0.5f -> -1).
371
372 \note This function does not guarantee correctness for high precisions.
373
374 Example:
375
376 \snippet code/src_corelib_global_qglobal.cpp 11B
377
378 \note If the value \a d is outside the range of \c int,
379 the behavior is undefined.
380*/
381
382/*! \fn qint64 qRound64(double d)
383 \relates <QtNumeric>
384
385 Rounds \a d to the nearest 64-bit integer.
386
387 Rounds half away from zero (e.g. 0.5 -> 1, -0.5 -> -1).
388
389 \note This function does not guarantee correctness for high precisions.
390
391 Example:
392
393 \snippet code/src_corelib_global_qglobal.cpp 12A
394
395 \note If the value \a d is outside the range of \c qint64,
396 the behavior is undefined.
397*/
398
399/*! \fn qint64 qRound64(float d)
400 \relates <QtNumeric>
401
402 Rounds \a d to the nearest 64-bit integer.
403
404 Rounds half away from zero (e.g. 0.5f -> 1, -0.5f -> -1).
405
406 \note This function does not guarantee correctness for high precisions.
407
408 Example:
409
410 \snippet code/src_corelib_global_qglobal.cpp 12B
411
412 \note If the value \a d is outside the range of \c qint64,
413 the behavior is undefined.
414*/
415
416/*!
417 \fn bool qFuzzyCompare(double p1, double p2)
418 \relates <QtNumeric>
419 \since 4.4
420 \threadsafe
421
422 Compares the floating point value \a p1 and \a p2 and
423 returns \c true if they are considered equal, otherwise \c false.
424
425 Note that comparing values where either \a p1 or \a p2 is 0.0 will not work,
426 nor does comparing values where one of the values is NaN or infinity.
427 If one of the values is always 0.0, use qFuzzyIsNull instead. If one of the
428 values is likely to be 0.0, one solution is to add 1.0 to both values.
429
430 \snippet code/src_corelib_global_qglobal.cpp 46
431
432 The two numbers are compared in a relative way, where the
433 exactness is stronger the smaller the numbers are.
434*/
435
436/*!
437 \fn bool qFuzzyCompare(float p1, float p2)
438 \relates <QtNumeric>
439 \since 4.4
440 \threadsafe
441
442 Compares the floating point value \a p1 and \a p2 and
443 returns \c true if they are considered equal, otherwise \c false.
444
445 The two numbers are compared in a relative way, where the
446 exactness is stronger the smaller the numbers are.
447*/
448
449/*!
450 \fn bool qFuzzyIsNull(double d)
451 \relates <QtNumeric>
452 \since 4.4
453 \threadsafe
454
455 Returns true if the absolute value of \a d is within 0.000000000001 of 0.0.
456*/
457
458/*!
459 \fn bool qFuzzyIsNull(float f)
460 \relates <QtNumeric>
461 \since 4.4
462 \threadsafe
463
464 Returns true if the absolute value of \a f is within 0.00001f of 0.0.
465*/
466
467namespace q20 {
468static_assert(rotl(1U, 1) == 2);
469static_assert(rotl(0x8000'0000U, 1) == 1);
470static_assert(rotl(0x8000'0001U, 1) == 3);
471static_assert(rotl(1U, -1) == 0x8000'0000U);
472static_assert(rotl(0x8000'0000U, -1) == 0x4000'0000U);
473static_assert(rotl(0x8000'0001U, -1) == 0xc000'0000U);
474
475static_assert(rotr(1U, 1) == 0x8000'0000U);
476static_assert(rotr(0x8000'0000U, 1) == 0x4000'0000U);
477static_assert(rotr(0x8000'0001U, 1) == 0xc000'0000U);
478static_assert(rotr(1U, -1) == 2);
479static_assert(rotr(0x8000'0000U, -1) == 1);
480static_assert(rotr(0x8000'0001U, -1) == 3);
481}
482
483QT_END_NAMESPACE
Combined button and popup list for selecting options.
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)