Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qfloat16.h
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2016 by Southwest Research Institute (R)
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QFLOAT16_H
6#define QFLOAT16_H
7
8#include <QtCore/qglobal.h>
9#include <QtCore/qmath.h>
10#include <QtCore/qnamespace.h>
11#include <limits>
12#include <string.h>
13
14#if defined(__STDCPP_FLOAT16_T__) && __has_include(<stdfloat>)
15// P1467 implementation - https://wg21.link/p1467
16# include <stdfloat>
17#endif
18
19#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__AVX2__) && !defined(__F16C__)
20// All processors that support AVX2 do support F16C too, so we could enable the
21// feature unconditionally if __AVX2__ is defined. However, all currently
22// supported compilers except Microsoft's are able to define __F16C__ on their
23// own when the user enables the feature, so we'll trust them.
24# if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
25# define __F16C__ 1
26# endif
27#endif
28
29#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
30#include <immintrin.h>
31#endif
32
34
35#if 0
36#pragma qt_class(QFloat16)
37#pragma qt_no_master_include
38#endif
39
40#ifndef QT_NO_DATASTREAM
41class QDataStream;
42#endif
43class QTextStream;
44
46{
47 struct Wrap
48 {
49 // To let our private constructor work, without other code seeing
50 // ambiguity when constructing from int, double &c.
51 quint16 b16;
52 constexpr inline explicit Wrap(int value) : b16(quint16(value)) {}
53 };
54
55public:
56#if defined(__STDCPP_FLOAT16_T__)
57# define QFLOAT16_IS_NATIVE 1
58 using NativeType = std::float16_t;
59#elif defined(Q_CC_CLANG) && defined(__FLT16_MAX__) && 0
60 // disabled due to https://github.com/llvm/llvm-project/issues/56963
61# define QFLOAT16_IS_NATIVE 1
62 using NativeType = decltype(__FLT16_MAX__);
63#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__)
64# define QFLOAT16_IS_NATIVE 1
65# ifdef __ARM_FP16_FORMAT_IEEE
66 using NativeType = __fp16;
67# else
68 using NativeType = _Float16;
69# endif
70#else
71# define QFLOAT16_IS_NATIVE 0
73#endif
74 static constexpr bool IsNative = QFLOAT16_IS_NATIVE;
75 using NearestFloat = std::conditional_t<IsNative, NativeType, float>;
76
77 constexpr inline qfloat16() noexcept : b16(0) {}
78 explicit qfloat16(Qt::Initialization) noexcept { }
79
80#if QFLOAT16_IS_NATIVE
81 constexpr inline qfloat16(NativeType f) : nf(f) {}
82 constexpr operator NativeType() const noexcept { return nf; }
83#else
84 inline qfloat16(float f) noexcept;
85 inline operator float() const noexcept;
86#endif
87 template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T> && !std::is_same_v<T, NearestFloat>>>
88 constexpr explicit qfloat16(T value) noexcept : qfloat16(NearestFloat(value)) {}
89
90 // Support for qIs{Inf,NaN,Finite}:
91 bool isInf() const noexcept { return (b16 & 0x7fff) == 0x7c00; }
92 bool isNaN() const noexcept { return (b16 & 0x7fff) > 0x7c00; }
93 bool isFinite() const noexcept { return (b16 & 0x7fff) < 0x7c00; }
94 Q_CORE_EXPORT int fpClassify() const noexcept;
95 // Can't specialize std::copysign() for qfloat16
97 { return qfloat16(Wrap((sign.b16 & 0x8000) | (b16 & 0x7fff))); }
98 // Support for std::numeric_limits<qfloat16>
99 static constexpr qfloat16 _limit_epsilon() noexcept { return qfloat16(Wrap(0x1400)); }
100 static constexpr qfloat16 _limit_min() noexcept { return qfloat16(Wrap(0x400)); }
101 static constexpr qfloat16 _limit_denorm_min() noexcept { return qfloat16(Wrap(1)); }
102 static constexpr qfloat16 _limit_max() noexcept { return qfloat16(Wrap(0x7bff)); }
103 static constexpr qfloat16 _limit_lowest() noexcept { return qfloat16(Wrap(0xfbff)); }
104 static constexpr qfloat16 _limit_infinity() noexcept { return qfloat16(Wrap(0x7c00)); }
105 static constexpr qfloat16 _limit_quiet_NaN() noexcept { return qfloat16(Wrap(0x7e00)); }
106#if QT_CONFIG(signaling_nan)
107 static constexpr qfloat16 _limit_signaling_NaN() noexcept { return qfloat16(Wrap(0x7d00)); }
108#endif
109 inline constexpr bool isNormal() const noexcept
110 { return (b16 & 0x7c00) && (b16 & 0x7c00) != 0x7c00; }
111private:
112 // ABI note: Qt 6's qfloat16 began with just a quint16 member so it ended
113 // up passed in general purpose registers in any function call taking
114 // qfloat16 by value (it has trivial copy constructors). This means the
115 // integer member in the anonymous union below must remain until a
116 // binary-incompatible version of Qt. If you remove it, on platforms using
117 // the System V ABI for C, the native type is passed in FP registers.
118 union {
120#if QFLOAT16_IS_NATIVE
121 NativeType nf;
122#endif
123 };
124 constexpr inline explicit qfloat16(Wrap nibble) noexcept : b16(nibble.b16) {}
125
126 Q_CORE_EXPORT static const quint32 mantissatable[];
127 Q_CORE_EXPORT static const quint32 exponenttable[];
128 Q_CORE_EXPORT static const quint32 offsettable[];
129 Q_CORE_EXPORT static const quint16 basetable[];
130 Q_CORE_EXPORT static const quint16 shifttable[];
131 Q_CORE_EXPORT static const quint32 roundtable[];
132
133 friend bool qIsNull(qfloat16 f) noexcept;
134
135 friend inline qfloat16 operator-(qfloat16 a) noexcept
136 {
137 qfloat16 f;
138 f.b16 = a.b16 ^ quint16(0x8000);
139 return f;
140 }
141
142 friend inline qfloat16 operator+(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) + static_cast<NearestFloat>(b)); }
143 friend inline qfloat16 operator-(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) - static_cast<NearestFloat>(b)); }
144 friend inline qfloat16 operator*(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) * static_cast<NearestFloat>(b)); }
145 friend inline qfloat16 operator/(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) / static_cast<NearestFloat>(b)); }
146
147#define QF16_MAKE_ARITH_OP_FP(FP, OP) \
148 friend inline FP operator OP(qfloat16 lhs, FP rhs) noexcept { return static_cast<FP>(lhs) OP rhs; } \
149 friend inline FP operator OP(FP lhs, qfloat16 rhs) noexcept { return lhs OP static_cast<FP>(rhs); }
150#define QF16_MAKE_ARITH_OP_EQ_FP(FP, OP_EQ, OP) \
151 friend inline qfloat16& operator OP_EQ(qfloat16& lhs, FP rhs) noexcept \
152 { lhs = qfloat16(NearestFloat(static_cast<FP>(lhs) OP rhs)); return lhs; }
153#define QF16_MAKE_ARITH_OP(FP) \
154 QF16_MAKE_ARITH_OP_FP(FP, +) \
155 QF16_MAKE_ARITH_OP_FP(FP, -) \
156 QF16_MAKE_ARITH_OP_FP(FP, *) \
157 QF16_MAKE_ARITH_OP_FP(FP, /) \
158 QF16_MAKE_ARITH_OP_EQ_FP(FP, +=, +) \
159 QF16_MAKE_ARITH_OP_EQ_FP(FP, -=, -) \
160 QF16_MAKE_ARITH_OP_EQ_FP(FP, *=, *) \
161 QF16_MAKE_ARITH_OP_EQ_FP(FP, /=, /)
162
163 QF16_MAKE_ARITH_OP(long double)
164 QF16_MAKE_ARITH_OP(double)
165 QF16_MAKE_ARITH_OP(float)
166#if QFLOAT16_IS_NATIVE
168#endif
169#undef QF16_MAKE_ARITH_OP
170#undef QF16_MAKE_ARITH_OP_FP
171
172#define QF16_MAKE_ARITH_OP_INT(OP) \
173 friend inline double operator OP(qfloat16 lhs, int rhs) noexcept { return static_cast<double>(lhs) OP rhs; } \
174 friend inline double operator OP(int lhs, qfloat16 rhs) noexcept { return lhs OP static_cast<double>(rhs); }
175
180#undef QF16_MAKE_ARITH_OP_INT
181
184
185 friend inline bool operator>(qfloat16 a, qfloat16 b) noexcept { return static_cast<NearestFloat>(a) > static_cast<NearestFloat>(b); }
186 friend inline bool operator<(qfloat16 a, qfloat16 b) noexcept { return static_cast<NearestFloat>(a) < static_cast<NearestFloat>(b); }
187 friend inline bool operator>=(qfloat16 a, qfloat16 b) noexcept { return static_cast<NearestFloat>(a) >= static_cast<NearestFloat>(b); }
188 friend inline bool operator<=(qfloat16 a, qfloat16 b) noexcept { return static_cast<NearestFloat>(a) <= static_cast<NearestFloat>(b); }
189 friend inline bool operator==(qfloat16 a, qfloat16 b) noexcept { return static_cast<NearestFloat>(a) == static_cast<NearestFloat>(b); }
190 friend inline bool operator!=(qfloat16 a, qfloat16 b) noexcept { return static_cast<NearestFloat>(a) != static_cast<NearestFloat>(b); }
191
192#define QF16_MAKE_BOOL_OP_FP(FP, OP) \
193 friend inline bool operator OP(qfloat16 lhs, FP rhs) noexcept { return static_cast<FP>(lhs) OP rhs; } \
194 friend inline bool operator OP(FP lhs, qfloat16 rhs) noexcept { return lhs OP static_cast<FP>(rhs); }
195#define QF16_MAKE_BOOL_OP(FP) \
196 QF16_MAKE_BOOL_OP_FP(FP, <) \
197 QF16_MAKE_BOOL_OP_FP(FP, >) \
198 QF16_MAKE_BOOL_OP_FP(FP, >=) \
199 QF16_MAKE_BOOL_OP_FP(FP, <=) \
200 QF16_MAKE_BOOL_OP_FP(FP, ==) \
201 QF16_MAKE_BOOL_OP_FP(FP, !=)
202
203 QF16_MAKE_BOOL_OP(long double)
204 QF16_MAKE_BOOL_OP(double)
205 QF16_MAKE_BOOL_OP(float)
206#undef QF16_MAKE_BOOL_OP
207#undef QF16_MAKE_BOOL_OP_FP
208
209#define QF16_MAKE_BOOL_OP_INT(OP) \
210 friend inline bool operator OP(qfloat16 a, int b) noexcept { return static_cast<NearestFloat>(a) OP static_cast<NearestFloat>(b); } \
211 friend inline bool operator OP(int a, qfloat16 b) noexcept { return static_cast<NearestFloat>(a) OP static_cast<NearestFloat>(b); }
212
219#undef QF16_MAKE_BOOL_OP_INT
220
222
223#ifndef QT_NO_DATASTREAM
224 friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &ds, qfloat16 f);
225 friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &ds, qfloat16 &f);
226#endif
227 friend Q_CORE_EXPORT QTextStream &operator<<(QTextStream &ts, qfloat16 f);
228 friend Q_CORE_EXPORT QTextStream &operator>>(QTextStream &ts, qfloat16 &f);
229};
230
232
233Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *, const float *, qsizetype length) noexcept;
234Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qsizetype length) noexcept;
235
236// Complement qnumeric.h:
237[[nodiscard]] inline bool qIsInf(qfloat16 f) noexcept { return f.isInf(); }
238[[nodiscard]] inline bool qIsNaN(qfloat16 f) noexcept { return f.isNaN(); }
239[[nodiscard]] inline bool qIsFinite(qfloat16 f) noexcept { return f.isFinite(); }
240[[nodiscard]] inline int qFpClassify(qfloat16 f) noexcept { return f.fpClassify(); }
241// [[nodiscard]] quint32 qFloatDistance(qfloat16 a, qfloat16 b);
242
243[[nodiscard]] inline qfloat16 qSqrt(qfloat16 f)
244{
245#if defined(__cpp_lib_extended_float) && defined(__STDCPP_FLOAT16_T__) && 0
246 // https://wg21.link/p1467 - disabled until tested
247 using namespace std;
248 return sqrt(f);
249#elif QFLOAT16_IS_NATIVE && defined(__HAVE_FLOAT16) && __HAVE_FLOAT16
250 // This C library (glibc) has sqrtf16().
251 return sqrtf16(f);
252#else
253 bool mathUpdatesErrno = true;
254# if defined(__NO_MATH_ERRNO__) || defined(_M_FP_FAST)
255 mathUpdatesErrno = false;
256# elif defined(math_errhandling)
257 mathUpdatesErrno = (math_errhandling & MATH_ERRNO);
258# endif
259
260 // We don't need to set errno to EDOM if (f >= 0 && f != -0 && !isnan(f))
261 // (or if we don't care about errno in the first place). We can merge the
262 // NaN check with by negating and inverting: !(0 > f), and leaving zero to
263 // sqrtf().
264 if (!mathUpdatesErrno || !(0 > f)) {
265# if defined(__AVX512FP16__)
266 __m128h v = _mm_set_sh(f);
267 v = _mm_sqrt_sh(v, v);
268 return _mm_cvtsh_h(v);
269# endif
270 }
271
272 // WG14's N2601 does not provide a way to tell which types an
273 // implementation supports, so we assume it doesn't and fall back to FP32
274 float f32 = float(f);
275 f32 = sqrtf(f32);
276 return qfloat16::NearestFloat(f32);
277#endif
278}
279
280// The remainder of these utility functions complement qglobal.h
281[[nodiscard]] inline int qRound(qfloat16 d) noexcept
282{ return qRound(static_cast<float>(d)); }
283
284[[nodiscard]] inline qint64 qRound64(qfloat16 d) noexcept
285{ return qRound64(static_cast<float>(d)); }
286
287[[nodiscard]] inline bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
288{
291 // The significand precision for IEEE754 half precision is
292 // 11 bits (10 explicitly stored), or approximately 3 decimal
293 // digits. In selecting the fuzzy comparison factor of 102.5f
294 // (that is, (2^10+1)/10) below, we effectively select a
295 // window of about 1 (least significant) decimal digit about
296 // which the two operands can vary and still return true.
297 return (qAbs(f1 - f2) * 102.5f <= qMin(qAbs(f1), qAbs(f2)));
298}
299
303[[nodiscard]] inline bool qFuzzyIsNull(qfloat16 f) noexcept
304{
305 return qAbs(f) < 0.00976f; // 1/102.5 to 3 significant digits; see qFuzzyCompare()
306}
307
308[[nodiscard]] inline bool qIsNull(qfloat16 f) noexcept
309{
310 return (f.b16 & static_cast<quint16>(0x7fff)) == 0;
311}
312
313inline int qIntCast(qfloat16 f) noexcept
314{ return int(static_cast<qfloat16::NearestFloat>(f)); }
315
316#if !defined(Q_QDOC) && !QFLOAT16_IS_NATIVE
318QT_WARNING_DISABLE_CLANG("-Wc99-extensions")
319QT_WARNING_DISABLE_GCC("-Wold-style-cast")
320inline qfloat16::qfloat16(float f) noexcept
321{
322#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
323 __m128 packsingle = _mm_set_ss(f);
324 __m128i packhalf = _mm_cvtps_ph(packsingle, 0);
325 b16 = _mm_extract_epi16(packhalf, 0);
326#elif defined (__ARM_FP16_FORMAT_IEEE)
327 __fp16 f16 = __fp16(f);
328 memcpy(&b16, &f16, sizeof(quint16));
329#else
330 quint32 u;
331 memcpy(&u, &f, sizeof(quint32));
332 const quint32 signAndExp = u >> 23;
333 const quint16 base = basetable[signAndExp];
334 const quint16 shift = shifttable[signAndExp];
335 const quint32 round = roundtable[signAndExp];
336 quint32 mantissa = (u & 0x007fffff);
337 if ((signAndExp & 0xff) == 0xff) {
338 if (mantissa) // keep nan from truncating to inf
339 mantissa = qMax(1U << shift, mantissa);
340 } else {
341 // Round half to even. First round up by adding one in the most
342 // significant bit we'll be discarding:
343 mantissa += round;
344 // If the last bit we'll be keeping is now set, but all later bits are
345 // clear, we were at half and shouldn't have rounded up; decrement will
346 // clear this last kept bit. Any later set bit hides the decrement.
347 if (mantissa & (1 << shift))
348 --mantissa;
349 }
350
351 // We use add as the mantissa may overflow causing
352 // the exp part to shift exactly one value.
353 b16 = quint16(base + (mantissa >> shift));
354#endif
355}
357
358inline qfloat16::operator float() const noexcept
359{
360#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
361 __m128i packhalf = _mm_cvtsi32_si128(b16);
362 __m128 packsingle = _mm_cvtph_ps(packhalf);
363 return _mm_cvtss_f32(packsingle);
364#elif defined (__ARM_FP16_FORMAT_IEEE)
365 __fp16 f16;
366 memcpy(&f16, &b16, sizeof(quint16));
367 return float(f16);
368#else
369 quint32 u = mantissatable[offsettable[b16 >> 10] + (b16 & 0x3ff)]
370 + exponenttable[b16 >> 10];
371 float f;
372 memcpy(&f, &u, sizeof(quint32));
373 return f;
374#endif
375}
376#endif // Q_QDOC and non-native
377
378/*
379 qHypot compatibility; see ../kernel/qmath.h
380*/
381namespace QtPrivate {
382template <> struct QHypotType<qfloat16, qfloat16>
383{
384 using type = qfloat16;
385};
386template <typename R> struct QHypotType<R, qfloat16>
387{
388 using type = std::conditional_t<std::is_floating_point_v<R>, R, double>;
389};
390template <typename R> struct QHypotType<qfloat16, R> : QHypotType<R, qfloat16>
391{
392};
393}
394
395// Avoid passing qfloat16 to std::hypot(), while ensuring return types
396// consistent with the above:
398{
399#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__) || QFLOAT16_IS_NATIVE
400 return QtPrivate::QHypotHelper<qfloat16>(x).add(y).result();
401#else
402 return qfloat16(qHypot(float(x), float(y)));
403#endif
404}
405
406// in ../kernel/qmath.h
407template<typename F, typename ...Fs> auto qHypot(F first, Fs... rest);
408
409template <typename T> typename QtPrivate::QHypotType<T, qfloat16>::type
411{
412 if constexpr (std::is_floating_point_v<T>)
413 return qHypot(x, float(y));
414 else
415 return qHypot(qfloat16(x), y);
416}
417template <typename T> auto qHypot(qfloat16 x, T y)
418{
419 return qHypot(y, x);
420}
421
422#if defined(__cpp_lib_hypot) && __cpp_lib_hypot >= 201603L // Expected to be true
423// If any are not qfloat16, convert each qfloat16 to float:
424/* (The following splits the some-but-not-all-qfloat16 cases up, using
425 (X|Y|Z)&~(X&Y&Z) = X ? ~(Y&Z) : Y|Z = X&~(Y&Z) | ~X&Y | ~X&~Y&Z,
426 into non-overlapping cases, to avoid ambiguity.) */
427template <typename Ty, typename Tz,
428 typename std::enable_if<
429 // Ty, Tz aren't both qfloat16:
430 !(std::is_same_v<qfloat16, Ty> && std::is_same_v<qfloat16, Tz>), int>::type = 0>
431auto qHypot(qfloat16 x, Ty y, Tz z) { return qHypot(qfloat16::NearestFloat(x), y, z); }
432template <typename Tx, typename Tz,
433 typename std::enable_if<
434 // Tx isn't qfloat16:
435 !std::is_same_v<qfloat16, Tx>, int>::type = 0>
436auto qHypot(Tx x, qfloat16 y, Tz z) { return qHypot(x, qfloat16::NearestFloat(y), z); }
437template <typename Tx, typename Ty,
438 typename std::enable_if<
439 // Neither Tx nor Ty is qfloat16:
440 !std::is_same_v<qfloat16, Tx> && !std::is_same_v<qfloat16, Ty>, int>::type = 0>
441auto qHypot(Tx x, Ty y, qfloat16 z) { return qHypot(x, y, qfloat16::NearestFloat(z)); }
442
443// If all are qfloat16, stay with qfloat16 (albeit via float, if no native support):
444inline auto qHypot(qfloat16 x, qfloat16 y, qfloat16 z)
445{
446#if (defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)) || QFLOAT16_IS_NATIVE
447 return QtPrivate::QHypotHelper<qfloat16>(x).add(y).add(z).result();
448#else
449 return qfloat16(qHypot(float(x), float(y), float(z)));
450#endif
451}
452#endif // 3-arg std::hypot() is available
453
455
456namespace std {
457template<>
458class numeric_limits<QT_PREPEND_NAMESPACE(qfloat16)> : public numeric_limits<float>
459{
460public:
461 /*
462 Treat quint16 b16 as if it were:
463 uint S: 1; // b16 >> 15 (sign); can be set for zero
464 uint E: 5; // (b16 >> 10) & 0x1f (offset exponent)
465 uint M: 10; // b16 & 0x3ff (adjusted mantissa)
466
467 for E == 0: magnitude is M / 2.^{24}
468 for 0 < E < 31: magnitude is (1. + M / 2.^{10}) * 2.^{E - 15)
469 for E == 31: not finite
470 */
471 static constexpr int digits = 11;
472 static constexpr int min_exponent = -13;
473 static constexpr int max_exponent = 16;
474
475 static constexpr int digits10 = 3;
476 static constexpr int max_digits10 = 5;
477 static constexpr int min_exponent10 = -4;
478 static constexpr int max_exponent10 = 4;
479
481 { return QT_PREPEND_NAMESPACE(qfloat16)::_limit_epsilon(); }
482 static constexpr QT_PREPEND_NAMESPACE(qfloat16) (min)()
483 { return QT_PREPEND_NAMESPACE(qfloat16)::_limit_min(); }
484 static constexpr QT_PREPEND_NAMESPACE(qfloat16) denorm_min()
485 { return QT_PREPEND_NAMESPACE(qfloat16)::_limit_denorm_min(); }
486 static constexpr QT_PREPEND_NAMESPACE(qfloat16) (max)()
487 { return QT_PREPEND_NAMESPACE(qfloat16)::_limit_max(); }
488 static constexpr QT_PREPEND_NAMESPACE(qfloat16) lowest()
489 { return QT_PREPEND_NAMESPACE(qfloat16)::_limit_lowest(); }
490 static constexpr QT_PREPEND_NAMESPACE(qfloat16) infinity()
491 { return QT_PREPEND_NAMESPACE(qfloat16)::_limit_infinity(); }
492 static constexpr QT_PREPEND_NAMESPACE(qfloat16) quiet_NaN()
493 { return QT_PREPEND_NAMESPACE(qfloat16)::_limit_quiet_NaN(); }
494#if QT_CONFIG(signaling_nan)
495 static constexpr QT_PREPEND_NAMESPACE(qfloat16) signaling_NaN()
496 { return QT_PREPEND_NAMESPACE(qfloat16)::_limit_signaling_NaN(); }
497#else
498 static constexpr bool has_signaling_NaN = false;
499#endif
500};
501
502template<> class numeric_limits<const QT_PREPEND_NAMESPACE(qfloat16)>
503 : public numeric_limits<QT_PREPEND_NAMESPACE(qfloat16)> {};
504template<> class numeric_limits<volatile QT_PREPEND_NAMESPACE(qfloat16)>
505 : public numeric_limits<QT_PREPEND_NAMESPACE(qfloat16)> {};
506template<> class numeric_limits<const volatile QT_PREPEND_NAMESPACE(qfloat16)>
507 : public numeric_limits<QT_PREPEND_NAMESPACE(qfloat16)> {};
508
509// Adding overloads to std isn't allowed, so we can't extend this to support
510// for fpclassify(), isnormal() &c. (which, furthermore, are macros on MinGW).
511} // namespace std
512
513#endif // QFLOAT16_H
\inmodule QtCore\reentrant
Definition qdatastream.h:30
\inmodule QtCore
auto add(F first, Fs... rest) const
Definition qmath.h:119
\keyword 16-bit Floating Point Support\inmodule QtCore \inheaderfile QFloat16
Definition qfloat16.h:46
constexpr qfloat16() noexcept
Definition qfloat16.h:77
quint16 b16
Definition qfloat16.h:119
constexpr bool isNormal() const noexcept
Definition qfloat16.h:109
static constexpr qfloat16 _limit_quiet_NaN() noexcept
Definition qfloat16.h:105
friend bool operator<(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:186
friend Q_CORE_EXPORT QDataStream & operator>>(QDataStream &ds, qfloat16 &f)
Definition qfloat16.cpp:395
friend bool operator!=(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:190
static constexpr qfloat16 _limit_min() noexcept
Definition qfloat16.h:100
bool isInf() const noexcept
Definition qfloat16.h:91
friend bool operator>=(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:187
void NativeType
Definition qfloat16.h:72
friend bool operator==(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:189
QT_WARNING_PUSH QT_WARNING_DISABLE_FLOAT_COMPARE friend bool operator>(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:185
static constexpr qfloat16 _limit_infinity() noexcept
Definition qfloat16.h:104
friend bool qIsNull(qfloat16 f) noexcept
Definition qfloat16.h:308
static constexpr qfloat16 _limit_epsilon() noexcept
Definition qfloat16.h:99
static constexpr bool IsNative
Definition qfloat16.h:74
QT_WARNING_POP friend Q_CORE_EXPORT QDataStream & operator<<(QDataStream &ds, qfloat16 f)
Definition qfloat16.cpp:378
static constexpr qfloat16 _limit_denorm_min() noexcept
Definition qfloat16.h:101
bool isNaN() const noexcept
Definition qfloat16.h:92
qfloat16(Qt::Initialization) noexcept
Definition qfloat16.h:78
friend qfloat16 operator/(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:145
friend bool operator<=(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:188
friend qfloat16 operator-(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:143
std::conditional_t< IsNative, NativeType, float > NearestFloat
Definition qfloat16.h:75
Q_CORE_EXPORT int fpClassify() const noexcept
Definition qfloat16.cpp:132
bool isFinite() const noexcept
Definition qfloat16.h:93
static constexpr qfloat16 _limit_lowest() noexcept
Definition qfloat16.h:103
friend qfloat16 operator+(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:142
friend qfloat16 operator*(qfloat16 a, qfloat16 b) noexcept
Definition qfloat16.h:144
friend qfloat16 operator-(qfloat16 a) noexcept
Definition qfloat16.h:135
qfloat16 copySign(qfloat16 sign) const noexcept
Definition qfloat16.h:96
static constexpr qfloat16 _limit_max() noexcept
Definition qfloat16.h:102
constexpr qfloat16(T value) noexcept
Definition qfloat16.h:88
static constexpr QT_PREPEND_NAMESPACE() qfloat16() max()
Definition qfloat16.h:486
static constexpr QT_PREPEND_NAMESPACE(qfloat16) lowest()
Definition qfloat16.h:488
static constexpr QT_PREPEND_NAMESPACE() qfloat16() min()
Definition qfloat16.h:482
static constexpr QT_PREPEND_NAMESPACE(qfloat16) epsilon()
Definition qfloat16.h:480
static constexpr QT_PREPEND_NAMESPACE(qfloat16) infinity()
Definition qfloat16.h:490
static constexpr QT_PREPEND_NAMESPACE(qfloat16) quiet_NaN()
Definition qfloat16.h:492
static constexpr QT_PREPEND_NAMESPACE(qfloat16) denorm_min()
Definition qfloat16.h:484
QPixmap p2
QPixmap p1
[0]
Combined button and popup list for selecting options.
\macro QT_NAMESPACE
Initialization
static QT_WARNING_DISABLE_FLOAT_COMPARE ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold)
Definition qbezier.cpp:309
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_FLOAT_COMPARE
#define QT_WARNING_DISABLE_GCC(text)
#define QT_WARNING_PUSH
#define QT_WARNING_DISABLE_CLANG(text)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define QF16_MAKE_ARITH_OP_INT(OP)
Definition qfloat16.h:172
bool qIsFinite(qfloat16 f) noexcept
Definition qfloat16.h:239
#define QF16_MAKE_ARITH_OP(FP)
Definition qfloat16.h:153
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
#define QF16_MAKE_BOOL_OP(FP)
Definition qfloat16.h:195
Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qsizetype length) noexcept
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
bool qIsNaN(qfloat16 f) noexcept
Definition qfloat16.h:238
int qFpClassify(qfloat16 f) noexcept
Definition qfloat16.h:240
#define QF16_MAKE_BOOL_OP_INT(OP)
Definition qfloat16.h:209
bool qIsInf(qfloat16 f) noexcept
Definition qfloat16.h:237
auto qHypot(qfloat16 x, qfloat16 y)
Definition qfloat16.h:397
bool qIsNull(qfloat16 f) noexcept
Definition qfloat16.h:308
#define QFLOAT16_IS_NATIVE
Definition qfloat16.h:71
Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *, const float *, qsizetype length) noexcept
qfloat16 qSqrt(qfloat16 f)
Definition qfloat16.h:243
qint64 qRound64(qfloat16 d) noexcept
Definition qfloat16.h:284
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:281
int qIntCast(qfloat16 f) noexcept
Definition qfloat16.h:313
static constexpr int digits(int number)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLenum GLsizei length
GLfloat GLfloat f
GLenum type
GLint first
GLint y
static const qreal epsilon
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:144
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:163
unsigned int quint32
Definition qtypes.h:45
unsigned short quint16
Definition qtypes.h:43
ptrdiff_t qsizetype
Definition qtypes.h:70
long long qint64
Definition qtypes.h:55
QT_END_NAMESPACE typedef QT_PREPEND_NAMESPACE(quintptr) WId
static int sign(int x)
std::conditional_t< std::is_floating_point_v< R >, R, double > type
Definition qfloat16.h:388
decltype(std::hypot(R(1), F(1))) type
Definition qmath.h:104