1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qnumeric.h"
41 #include "qnumeric_p.h"
42 #include <string.h>
43 
44 QT_BEGIN_NAMESPACE
45 
46 /*!
47     Returns \c true if the double \a {d} is equivalent to infinity.
48     \relates <QtGlobal>
49     \sa qInf()
50 */
qIsInf(double d)51 Q_CORE_EXPORT bool qIsInf(double d) { return qt_is_inf(d); }
52 
53 /*!
54     Returns \c true if the double \a {d} is not a number (NaN).
55     \relates <QtGlobal>
56 */
qIsNaN(double d)57 Q_CORE_EXPORT bool qIsNaN(double d) { return qt_is_nan(d); }
58 
59 /*!
60     Returns \c true if the double \a {d} is a finite number.
61     \relates <QtGlobal>
62 */
qIsFinite(double d)63 Q_CORE_EXPORT bool qIsFinite(double d) { return qt_is_finite(d); }
64 
65 /*!
66     Returns \c true if the float \a {f} is equivalent to infinity.
67     \relates <QtGlobal>
68     \sa qInf()
69 */
qIsInf(float f)70 Q_CORE_EXPORT bool qIsInf(float f) { return qt_is_inf(f); }
71 
72 /*!
73     Returns \c true if the float \a {f} is not a number (NaN).
74     \relates <QtGlobal>
75 */
qIsNaN(float f)76 Q_CORE_EXPORT bool qIsNaN(float f) { return qt_is_nan(f); }
77 
78 /*!
79     Returns \c true if the float \a {f} is a finite number.
80     \relates <QtGlobal>
81 */
qIsFinite(float f)82 Q_CORE_EXPORT bool qIsFinite(float f) { return qt_is_finite(f); }
83 
84 #if QT_CONFIG(signaling_nan)
85 /*!
86     Returns the bit pattern of a signalling NaN as a double.
87     \relates <QtGlobal>
88 */
qSNaN()89 Q_CORE_EXPORT double qSNaN() { return qt_snan(); }
90 #endif
91 
92 /*!
93     Returns the bit pattern of a quiet NaN as a double.
94     \relates <QtGlobal>
95     \sa qIsNaN()
96 */
qQNaN()97 Q_CORE_EXPORT double qQNaN() { return qt_qnan(); }
98 
99 /*!
100     Returns the bit pattern for an infinite number as a double.
101     \relates <QtGlobal>
102     \sa qIsInf()
103 */
qInf()104 Q_CORE_EXPORT double qInf() { return qt_inf(); }
105 
106 /*!
107     \relates <QtGlobal>
108     Classifies a floating-point value.
109 
110     The return values are defined in \c{<cmath>}: returns one of the following,
111     determined by the floating-point class of \a val:
112     \list
113     \li FP_NAN not a number
114     \li FP_INFINITE infinities (positive or negative)
115     \li FP_ZERO zero (positive or negative)
116     \li FP_NORMAL finite with a full mantissa
117     \li FP_SUBNORMAL finite with a reduced mantissa
118     \endlist
119 */
qFpClassify(double val)120 Q_CORE_EXPORT int qFpClassify(double val) { return qt_fpclassify(val); }
121 
122 /*!
123     \overload
124 */
qFpClassify(float val)125 Q_CORE_EXPORT int qFpClassify(float val) { return qt_fpclassify(val); }
126 
127 
128 /*!
129    \internal
130  */
f2i(float f)131 static inline quint32 f2i(float f)
132 {
133     quint32 i;
134     memcpy(&i, &f, sizeof(f));
135     return i;
136 }
137 
138 /*!
139     Returns the number of representable floating-point numbers between \a a and \a b.
140 
141     This function provides an alternative way of doing approximated comparisons of floating-point
142     numbers similar to qFuzzyCompare(). However, it returns the distance between two numbers, which
143     gives the caller a possibility to choose the accepted error. Errors are relative, so for
144     instance the distance between 1.0E-5 and 1.00001E-5 will give 110, while the distance between
145     1.0E36 and 1.00001E36 will give 127.
146 
147     This function is useful if a floating point comparison requires a certain precision.
148     Therefore, if \a a and \a b are equal it will return 0. The maximum value it will return for 32-bit
149     floating point numbers is 4,278,190,078. This is the distance between \c{-FLT_MAX} and
150     \c{+FLT_MAX}.
151 
152     The function does not give meaningful results if any of the arguments are \c Infinite or \c NaN.
153     You can check for this by calling qIsFinite().
154 
155     The return value can be considered as the "error", so if you for instance want to compare
156     two 32-bit floating point numbers and all you need is an approximated 24-bit precision, you can
157     use this function like this:
158 
159     \snippet code/src_corelib_global_qnumeric.cpp 0
160 
161     \sa qFuzzyCompare()
162     \since 5.2
163     \relates <QtGlobal>
164 */
qFloatDistance(float a,float b)165 Q_CORE_EXPORT quint32 qFloatDistance(float a, float b)
166 {
167     static const quint32 smallestPositiveFloatAsBits = 0x00000001;  // denormalized, (SMALLEST), (1.4E-45)
168     /* Assumes:
169        * IEE754 format.
170        * Integers and floats have the same endian
171     */
172     Q_STATIC_ASSERT(sizeof(quint32) == sizeof(float));
173     Q_ASSERT(qIsFinite(a) && qIsFinite(b));
174     if (a == b)
175         return 0;
176     if ((a < 0) != (b < 0)) {
177         // if they have different signs
178         if (a < 0)
179             a = -a;
180         else /*if (b < 0)*/
181             b = -b;
182         return qFloatDistance(0.0F, a) + qFloatDistance(0.0F, b);
183     }
184     if (a < 0) {
185         a = -a;
186         b = -b;
187     }
188     // at this point a and b should not be negative
189 
190     // 0 is special
191     if (!a)
192         return f2i(b) - smallestPositiveFloatAsBits + 1;
193     if (!b)
194         return f2i(a) - smallestPositiveFloatAsBits + 1;
195 
196     // finally do the common integer subtraction
197     return a > b ? f2i(a) - f2i(b) : f2i(b) - f2i(a);
198 }
199 
200 
201 /*!
202    \internal
203  */
d2i(double d)204 static inline quint64 d2i(double d)
205 {
206     quint64 i;
207     memcpy(&i, &d, sizeof(d));
208     return i;
209 }
210 
211 /*!
212     Returns the number of representable floating-point numbers between \a a and \a b.
213 
214     This function serves the same purpose as \c{qFloatDistance(float, float)}, but
215     returns the distance between two \c double numbers. Since the range is larger
216     than for two \c float numbers (\c{[-DBL_MAX,DBL_MAX]}), the return type is quint64.
217 
218 
219     \sa qFuzzyCompare()
220     \since 5.2
221     \relates <QtGlobal>
222 */
qFloatDistance(double a,double b)223 Q_CORE_EXPORT quint64 qFloatDistance(double a, double b)
224 {
225     static const quint64 smallestPositiveFloatAsBits = 0x1;  // denormalized, (SMALLEST)
226     /* Assumes:
227        * IEE754 format double precision
228        * Integers and floats have the same endian
229     */
230     Q_STATIC_ASSERT(sizeof(quint64) == sizeof(double));
231     Q_ASSERT(qIsFinite(a) && qIsFinite(b));
232     if (a == b)
233         return 0;
234     if ((a < 0) != (b < 0)) {
235         // if they have different signs
236         if (a < 0)
237             a = -a;
238         else /*if (b < 0)*/
239             b = -b;
240         return qFloatDistance(0.0, a) + qFloatDistance(0.0, b);
241     }
242     if (a < 0) {
243         a = -a;
244         b = -b;
245     }
246     // at this point a and b should not be negative
247 
248     // 0 is special
249     if (!a)
250         return d2i(b) - smallestPositiveFloatAsBits + 1;
251     if (!b)
252         return d2i(a) - smallestPositiveFloatAsBits + 1;
253 
254     // finally do the common integer subtraction
255     return a > b ? d2i(a) - d2i(b) : d2i(b) - d2i(a);
256 }
257 
258 
259 QT_END_NAMESPACE
260