Warning, file /include/QtCore/qmath.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004 #ifndef QMATH_H
0005 #define QMATH_H
0006
0007 #if 0
0008 #pragma qt_class(QtMath)
0009 #endif
0010
0011 #include <QtCore/qglobal.h>
0012 #include <QtCore/qalgorithms.h>
0013
0014 #if __has_include(<bit>) && __cplusplus > 201703L
0015 #include <bit>
0016 #endif
0017
0018 #ifndef _USE_MATH_DEFINES
0019 # define _USE_MATH_DEFINES
0020 # define undef_USE_MATH_DEFINES
0021 #endif
0022
0023 #include <cmath>
0024
0025 #ifdef undef_USE_MATH_DEFINES
0026 # undef _USE_MATH_DEFINES
0027 # undef undef_USE_MATH_DEFINES
0028 #endif
0029
0030 QT_BEGIN_NAMESPACE
0031
0032 #define QT_SINE_TABLE_SIZE 256
0033
0034 extern Q_CORE_EXPORT const qreal qt_sine_table[QT_SINE_TABLE_SIZE];
0035
0036 template <typename T> int qCeil(T v)
0037 {
0038 using std::ceil;
0039 return int(ceil(v));
0040 }
0041
0042 template <typename T> int qFloor(T v)
0043 {
0044 using std::floor;
0045 return int(floor(v));
0046 }
0047
0048 template <typename T> auto qFabs(T v)
0049 {
0050 using std::fabs;
0051 return fabs(v);
0052 }
0053
0054 template <typename T> auto qSin(T v)
0055 {
0056 using std::sin;
0057 return sin(v);
0058 }
0059
0060 template <typename T> auto qCos(T v)
0061 {
0062 using std::cos;
0063 return cos(v);
0064 }
0065
0066 template <typename T> auto qTan(T v)
0067 {
0068 using std::tan;
0069 return tan(v);
0070 }
0071
0072 template <typename T> auto qAcos(T v)
0073 {
0074 using std::acos;
0075 return acos(v);
0076 }
0077
0078 template <typename T> auto qAsin(T v)
0079 {
0080 using std::asin;
0081 return asin(v);
0082 }
0083
0084 template <typename T> auto qAtan(T v)
0085 {
0086 using std::atan;
0087 return atan(v);
0088 }
0089
0090 template <typename T1, typename T2> auto qAtan2(T1 y, T2 x)
0091 {
0092 using std::atan2;
0093 return atan2(y, x);
0094 }
0095
0096 template <typename T> auto qSqrt(T v)
0097 {
0098 using std::sqrt;
0099 return sqrt(v);
0100 }
0101
0102 namespace QtPrivate {
0103 template <typename R, typename F>
0104 struct QHypotType { using type = decltype(std::hypot(R(1), F(1))); };
0105
0106
0107 template <typename T>
0108 class QHypotHelper
0109 {
0110 T scale, total;
0111 template <typename F> friend class QHypotHelper;
0112 QHypotHelper(T first, T prior) : scale(first), total(prior) {}
0113 public:
0114 QHypotHelper(T first) : scale(qAbs(first)), total(1) {}
0115 T result() const
0116 { return qIsFinite(scale) ? scale > 0 ? scale * T(qSqrt(total)) : T(0) : scale; }
0117
0118 template<typename F, typename ...Fs>
0119 auto add(F first, Fs... rest) const
0120 { return add(first).add(rest...); }
0121
0122 template<typename F, typename R = typename QHypotType<T, F>::type>
0123 QHypotHelper<R> add(F next) const
0124 {
0125 if (qIsInf(scale) || (qIsNaN(scale) && !qIsInf(next)))
0126 return QHypotHelper<R>(scale, R(1));
0127 if (qIsNaN(next))
0128 return QHypotHelper<R>(next, R(1));
0129 const R val = qAbs(next);
0130 if (!(scale > 0) || qIsInf(next))
0131 return QHypotHelper<R>(val, R(1));
0132 if (!(val > 0))
0133 return QHypotHelper<R>(scale, total);
0134 if (val > scale) {
0135 const R ratio = scale / next;
0136 return QHypotHelper<R>(val, total * ratio * ratio + R(1));
0137 }
0138 const R ratio = next / scale;
0139 return QHypotHelper<R>(scale, total + ratio * ratio);
0140 }
0141 };
0142 }
0143
0144 template<typename F, typename ...Fs>
0145 auto qHypot(F first, Fs... rest)
0146 {
0147 return QtPrivate::QHypotHelper<F>(first).add(rest...).result();
0148 }
0149
0150
0151 template <typename Tx, typename Ty>
0152 auto qHypot(Tx x, Ty y)
0153 {
0154
0155 using std::hypot;
0156 return hypot(x, y);
0157 }
0158
0159 #if defined(__cpp_lib_hypot) && __cpp_lib_hypot >= 201603L
0160 template <typename Tx, typename Ty, typename Tz>
0161 auto qHypot(Tx x, Ty y, Tz z)
0162 {
0163 using std::hypot;
0164 return hypot(x, y, z);
0165 }
0166 #endif
0167
0168 template <typename T> auto qLn(T v)
0169 {
0170 using std::log;
0171 return log(v);
0172 }
0173
0174 template <typename T> auto qExp(T v)
0175 {
0176 using std::exp;
0177 return exp(v);
0178 }
0179
0180 template <typename T1, typename T2> auto qPow(T1 x, T2 y)
0181 {
0182 using std::pow;
0183 return pow(x, y);
0184 }
0185
0186
0187
0188 #ifndef M_E
0189 #define M_E (2.7182818284590452354)
0190 #endif
0191
0192 #ifndef M_LOG2E
0193 #define M_LOG2E (1.4426950408889634074)
0194 #endif
0195
0196 #ifndef M_LOG10E
0197 #define M_LOG10E (0.43429448190325182765)
0198 #endif
0199
0200 #ifndef M_LN2
0201 #define M_LN2 (0.69314718055994530942)
0202 #endif
0203
0204 #ifndef M_LN10
0205 #define M_LN10 (2.30258509299404568402)
0206 #endif
0207
0208 #ifndef M_PI
0209 #define M_PI (3.14159265358979323846)
0210 #endif
0211
0212 #ifndef M_PI_2
0213 #define M_PI_2 (1.57079632679489661923)
0214 #endif
0215
0216 #ifndef M_PI_4
0217 #define M_PI_4 (0.78539816339744830962)
0218 #endif
0219
0220 #ifndef M_1_PI
0221 #define M_1_PI (0.31830988618379067154)
0222 #endif
0223
0224 #ifndef M_2_PI
0225 #define M_2_PI (0.63661977236758134308)
0226 #endif
0227
0228 #ifndef M_2_SQRTPI
0229 #define M_2_SQRTPI (1.12837916709551257390)
0230 #endif
0231
0232 #ifndef M_SQRT2
0233 #define M_SQRT2 (1.41421356237309504880)
0234 #endif
0235
0236 #ifndef M_SQRT1_2
0237 #define M_SQRT1_2 (0.70710678118654752440)
0238 #endif
0239
0240 inline qreal qFastSin(qreal x)
0241 {
0242 int si = int(x * (0.5 * QT_SINE_TABLE_SIZE / M_PI));
0243 qreal d = x - si * (2.0 * M_PI / QT_SINE_TABLE_SIZE);
0244 int ci = si + QT_SINE_TABLE_SIZE / 4;
0245 si &= QT_SINE_TABLE_SIZE - 1;
0246 ci &= QT_SINE_TABLE_SIZE - 1;
0247 return qt_sine_table[si] + (qt_sine_table[ci] - 0.5 * qt_sine_table[si] * d) * d;
0248 }
0249
0250 inline qreal qFastCos(qreal x)
0251 {
0252 int ci = int(x * (0.5 * QT_SINE_TABLE_SIZE / M_PI));
0253 qreal d = x - ci * (2.0 * M_PI / QT_SINE_TABLE_SIZE);
0254 int si = ci + QT_SINE_TABLE_SIZE / 4;
0255 si &= QT_SINE_TABLE_SIZE - 1;
0256 ci &= QT_SINE_TABLE_SIZE - 1;
0257 return qt_sine_table[si] - (qt_sine_table[ci] + 0.5 * qt_sine_table[si] * d) * d;
0258 }
0259
0260 constexpr inline float qDegreesToRadians(float degrees)
0261 {
0262 return degrees * float(M_PI / 180);
0263 }
0264
0265 constexpr inline double qDegreesToRadians(double degrees)
0266 {
0267 return degrees * (M_PI / 180);
0268 }
0269
0270 constexpr inline long double qDegreesToRadians(long double degrees)
0271 {
0272 return degrees * (M_PI / 180);
0273 }
0274
0275 template <typename T, std::enable_if_t<std::is_integral_v<T>, bool> = true>
0276 constexpr inline double qDegreesToRadians(T degrees)
0277 {
0278 return qDegreesToRadians(static_cast<double>(degrees));
0279 }
0280
0281 constexpr inline float qRadiansToDegrees(float radians)
0282 {
0283 return radians * float(180 / M_PI);
0284 }
0285
0286 constexpr inline double qRadiansToDegrees(double radians)
0287 {
0288 return radians * (180 / M_PI);
0289 }
0290
0291 constexpr inline long double qRadiansToDegrees(long double radians)
0292 {
0293 return radians * (180 / M_PI);
0294 }
0295
0296
0297
0298
0299
0300 namespace QtPrivate {
0301 constexpr inline quint32 qConstexprNextPowerOfTwo(quint32 v)
0302 {
0303 v |= v >> 1;
0304 v |= v >> 2;
0305 v |= v >> 4;
0306 v |= v >> 8;
0307 v |= v >> 16;
0308 ++v;
0309 return v;
0310 }
0311
0312 constexpr inline quint64 qConstexprNextPowerOfTwo(quint64 v)
0313 {
0314 v |= v >> 1;
0315 v |= v >> 2;
0316 v |= v >> 4;
0317 v |= v >> 8;
0318 v |= v >> 16;
0319 v |= v >> 32;
0320 ++v;
0321 return v;
0322 }
0323
0324 constexpr inline quint32 qConstexprNextPowerOfTwo(qint32 v)
0325 {
0326 return qConstexprNextPowerOfTwo(quint32(v));
0327 }
0328
0329 constexpr inline quint64 qConstexprNextPowerOfTwo(qint64 v)
0330 {
0331 return qConstexprNextPowerOfTwo(quint64(v));
0332 }
0333 }
0334
0335 constexpr inline quint32 qNextPowerOfTwo(quint32 v)
0336 {
0337 Q_ASSERT(static_cast<qint32>(v) >= 0);
0338 #if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L
0339 return std::bit_ceil(v + 1);
0340 #elif defined(QT_HAS_BUILTIN_CLZ)
0341 if (v == 0)
0342 return 1;
0343 return 2U << (31 ^ QAlgorithmsPrivate::qt_builtin_clz(v));
0344 #else
0345 return QtPrivate::qConstexprNextPowerOfTwo(v);
0346 #endif
0347 }
0348
0349 constexpr inline quint64 qNextPowerOfTwo(quint64 v)
0350 {
0351 Q_ASSERT(static_cast<qint64>(v) >= 0);
0352 #if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L
0353 return std::bit_ceil(v + 1);
0354 #elif defined(QT_HAS_BUILTIN_CLZLL)
0355 if (v == 0)
0356 return 1;
0357 return Q_UINT64_C(2) << (63 ^ QAlgorithmsPrivate::qt_builtin_clzll(v));
0358 #else
0359 return QtPrivate::qConstexprNextPowerOfTwo(v);
0360 #endif
0361 }
0362
0363 constexpr inline quint32 qNextPowerOfTwo(qint32 v)
0364 {
0365 return qNextPowerOfTwo(quint32(v));
0366 }
0367
0368 constexpr inline quint64 qNextPowerOfTwo(qint64 v)
0369 {
0370 return qNextPowerOfTwo(quint64(v));
0371 }
0372
0373 constexpr inline unsigned long qNextPowerOfTwo(unsigned long v)
0374 {
0375 return qNextPowerOfTwo(QIntegerForSizeof<long>::Unsigned(v));
0376 }
0377
0378 constexpr inline unsigned long qNextPowerOfTwo(long v)
0379 {
0380 return qNextPowerOfTwo(QIntegerForSizeof<long>::Unsigned(v));
0381 }
0382
0383 QT_END_NAMESPACE
0384
0385 #endif