1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 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 #ifndef QMATH_H
41 #define QMATH_H
42 
43 #if 0
44 #pragma qt_class(QtMath)
45 #endif
46 
47 #include <QtCore/qglobal.h>
48 #include <QtCore/qalgorithms.h>
49 
50 #ifndef _USE_MATH_DEFINES
51 #  define _USE_MATH_DEFINES
52 #  define undef_USE_MATH_DEFINES
53 #endif
54 
55 #include <cmath>
56 
57 #ifdef undef_USE_MATH_DEFINES
58 #  undef _USE_MATH_DEFINES
59 #  undef undef_USE_MATH_DEFINES
60 #endif
61 
62 QT_BEGIN_NAMESPACE
63 
64 #define QT_SINE_TABLE_SIZE 256
65 
66 extern Q_CORE_EXPORT const qreal qt_sine_table[QT_SINE_TABLE_SIZE];
67 
qCeil(qreal v)68 inline int qCeil(qreal v)
69 {
70     using std::ceil;
71     return int(ceil(v));
72 }
73 
qFloor(qreal v)74 inline int qFloor(qreal v)
75 {
76     using std::floor;
77     return int(floor(v));
78 }
79 
qFabs(qreal v)80 inline qreal qFabs(qreal v)
81 {
82     using std::fabs;
83     return fabs(v);
84 }
85 
qSin(qreal v)86 inline qreal qSin(qreal v)
87 {
88     using std::sin;
89     return sin(v);
90 }
91 
qCos(qreal v)92 inline qreal qCos(qreal v)
93 {
94     using std::cos;
95     return cos(v);
96 }
97 
qTan(qreal v)98 inline qreal qTan(qreal v)
99 {
100     using std::tan;
101     return tan(v);
102 }
103 
qAcos(qreal v)104 inline qreal qAcos(qreal v)
105 {
106     using std::acos;
107     return acos(v);
108 }
109 
qAsin(qreal v)110 inline qreal qAsin(qreal v)
111 {
112     using std::asin;
113     return asin(v);
114 }
115 
qAtan(qreal v)116 inline qreal qAtan(qreal v)
117 {
118     using std::atan;
119     return atan(v);
120 }
121 
qAtan2(qreal y,qreal x)122 inline qreal qAtan2(qreal y, qreal x)
123 {
124     using std::atan2;
125     return atan2(y, x);
126 }
127 
qSqrt(qreal v)128 inline qreal qSqrt(qreal v)
129 {
130     using std::sqrt;
131     return sqrt(v);
132 }
133 
qLn(qreal v)134 inline qreal qLn(qreal v)
135 {
136     using std::log;
137     return log(v);
138 }
139 
qExp(qreal v)140 inline qreal qExp(qreal v)
141 {
142     using std::exp;
143     return exp(v);
144 }
145 
qPow(qreal x,qreal y)146 inline qreal qPow(qreal x, qreal y)
147 {
148     using std::pow;
149     return pow(x, y);
150 }
151 
152 // TODO: use template variables (e.g. Qt::pi<type>) for these once we have C++14 support:
153 
154 #ifndef M_E
155 #define M_E (2.7182818284590452354)
156 #endif
157 
158 #ifndef M_LOG2E
159 #define M_LOG2E (1.4426950408889634074)
160 #endif
161 
162 #ifndef M_LOG10E
163 #define M_LOG10E (0.43429448190325182765)
164 #endif
165 
166 #ifndef M_LN2
167 #define M_LN2 (0.69314718055994530942)
168 #endif
169 
170 #ifndef M_LN10
171 #define M_LN10 (2.30258509299404568402)
172 #endif
173 
174 #ifndef M_PI
175 #define M_PI (3.14159265358979323846)
176 #endif
177 
178 #ifndef M_PI_2
179 #define M_PI_2 (1.57079632679489661923)
180 #endif
181 
182 #ifndef M_PI_4
183 #define M_PI_4 (0.78539816339744830962)
184 #endif
185 
186 #ifndef M_1_PI
187 #define M_1_PI (0.31830988618379067154)
188 #endif
189 
190 #ifndef M_2_PI
191 #define M_2_PI (0.63661977236758134308)
192 #endif
193 
194 #ifndef M_2_SQRTPI
195 #define M_2_SQRTPI (1.12837916709551257390)
196 #endif
197 
198 #ifndef M_SQRT2
199 #define M_SQRT2 (1.41421356237309504880)
200 #endif
201 
202 #ifndef M_SQRT1_2
203 #define M_SQRT1_2 (0.70710678118654752440)
204 #endif
205 
qFastSin(qreal x)206 inline qreal qFastSin(qreal x)
207 {
208     int si = int(x * (0.5 * QT_SINE_TABLE_SIZE / M_PI)); // Would be more accurate with qRound, but slower.
209     qreal d = x - si * (2.0 * M_PI / QT_SINE_TABLE_SIZE);
210     int ci = si + QT_SINE_TABLE_SIZE / 4;
211     si &= QT_SINE_TABLE_SIZE - 1;
212     ci &= QT_SINE_TABLE_SIZE - 1;
213     return qt_sine_table[si] + (qt_sine_table[ci] - 0.5 * qt_sine_table[si] * d) * d;
214 }
215 
qFastCos(qreal x)216 inline qreal qFastCos(qreal x)
217 {
218     int ci = int(x * (0.5 * QT_SINE_TABLE_SIZE / M_PI)); // Would be more accurate with qRound, but slower.
219     qreal d = x - ci * (2.0 * M_PI / QT_SINE_TABLE_SIZE);
220     int si = ci + QT_SINE_TABLE_SIZE / 4;
221     si &= QT_SINE_TABLE_SIZE - 1;
222     ci &= QT_SINE_TABLE_SIZE - 1;
223     return qt_sine_table[si] - (qt_sine_table[ci] + 0.5 * qt_sine_table[si] * d) * d;
224 }
225 
qDegreesToRadians(float degrees)226 Q_DECL_CONSTEXPR inline float qDegreesToRadians(float degrees)
227 {
228     return degrees * float(M_PI/180);
229 }
230 
qDegreesToRadians(double degrees)231 Q_DECL_CONSTEXPR inline double qDegreesToRadians(double degrees)
232 {
233     return degrees * (M_PI / 180);
234 }
235 
qRadiansToDegrees(float radians)236 Q_DECL_CONSTEXPR inline float qRadiansToDegrees(float radians)
237 {
238     return radians * float(180/M_PI);
239 }
240 
qRadiansToDegrees(double radians)241 Q_DECL_CONSTEXPR inline double qRadiansToDegrees(double radians)
242 {
243     return radians * (180 / M_PI);
244 }
245 
246 
qNextPowerOfTwo(quint32 v)247 Q_DECL_RELAXED_CONSTEXPR inline quint32 qNextPowerOfTwo(quint32 v)
248 {
249 #if defined(QT_HAS_BUILTIN_CLZ)
250     if (v == 0)
251         return 1;
252     return 2U << (31 ^ QAlgorithmsPrivate::qt_builtin_clz(v));
253 #else
254     v |= v >> 1;
255     v |= v >> 2;
256     v |= v >> 4;
257     v |= v >> 8;
258     v |= v >> 16;
259     ++v;
260     return v;
261 #endif
262 }
263 
qNextPowerOfTwo(quint64 v)264 Q_DECL_RELAXED_CONSTEXPR inline quint64 qNextPowerOfTwo(quint64 v)
265 {
266 #if defined(QT_HAS_BUILTIN_CLZLL)
267     if (v == 0)
268         return 1;
269     return Q_UINT64_C(2) << (63 ^ QAlgorithmsPrivate::qt_builtin_clzll(v));
270 #else
271     v |= v >> 1;
272     v |= v >> 2;
273     v |= v >> 4;
274     v |= v >> 8;
275     v |= v >> 16;
276     v |= v >> 32;
277     ++v;
278     return v;
279 #endif
280 }
281 
qNextPowerOfTwo(qint32 v)282 Q_DECL_RELAXED_CONSTEXPR inline quint32 qNextPowerOfTwo(qint32 v)
283 {
284     return qNextPowerOfTwo(quint32(v));
285 }
286 
qNextPowerOfTwo(qint64 v)287 Q_DECL_RELAXED_CONSTEXPR inline quint64 qNextPowerOfTwo(qint64 v)
288 {
289     return qNextPowerOfTwo(quint64(v));
290 }
291 
292 QT_END_NAMESPACE
293 
294 #endif // QMATH_H
295