diff options
-rw-r--r-- | src/corelib/global/qfloat16.cpp | 2 | ||||
-rw-r--r-- | src/corelib/global/qfloat16.h | 4 | ||||
-rw-r--r-- | tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp | 13 |
3 files changed, 15 insertions, 4 deletions
diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp index 2ba4c79374..6c21b7de5a 100644 --- a/src/corelib/global/qfloat16.cpp +++ b/src/corelib/global/qfloat16.cpp @@ -155,7 +155,7 @@ QT_BEGIN_NAMESPACE int qfloat16::fpClassify() const noexcept { return isInf() ? FP_INFINITE : isNaN() ? FP_NAN - : !b16 ? FP_ZERO : isNormal() ? FP_NORMAL : FP_SUBNORMAL; + : !(b16 & 0x7fff) ? FP_ZERO : isNormal() ? FP_NORMAL : FP_SUBNORMAL; } /*! \fn int qRound(qfloat16 value) diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h index 4d1aa91349..9a4f1800a4 100644 --- a/src/corelib/global/qfloat16.h +++ b/src/corelib/global/qfloat16.h @@ -94,7 +94,7 @@ public: static constexpr qfloat16 _limit_quiet_NaN() noexcept { return qfloat16(Wrap(0x7e00)); } // Signalling NaN is 0x7f00 inline constexpr bool isNormal() const noexcept - { return b16 == 0 || ((b16 & 0x7c00) && (b16 & 0x7c00) != 0x7c00); } + { return (b16 & 0x7fff) == 0 || ((b16 & 0x7c00) && (b16 & 0x7c00) != 0x7c00); } private: quint16 b16; constexpr inline explicit qfloat16(Wrap nibble) noexcept : b16(nibble.b16) {} @@ -296,7 +296,7 @@ class numeric_limits<QT_PREPEND_NAMESPACE(qfloat16)> : public numeric_limits<flo public: /* Treat quint16 b16 as if it were: - uint S: 1; // b16 >> 15 (sign) + uint S: 1; // b16 >> 15 (sign); can be set for zero uint E: 5; // (b16 >> 10) & 0x1f (offset exponent) uint M: 10; // b16 & 0x3ff (adjusted mantissa) diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp index 01a1789188..94f0afa5ed 100644 --- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp +++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp @@ -107,6 +107,7 @@ void tst_qfloat16::ltgt_data() QTest::addColumn<float>("val2"); QTest::newRow("zero") << 0.0f << 0.0f; + QTest::newRow("-zero") << -0.0f << 0.0f; QTest::newRow("ten") << 10.0f << 10.0f; QTest::newRow("large") << 100000.0f << 100000.0f; QTest::newRow("small") << 0.0000001f << 0.0000001f; @@ -405,6 +406,7 @@ void tst_qfloat16::finite_data() QTest::addColumn<int>("mode"); QTest::newRow("zero") << qfloat16(0) << FP_ZERO; + QTest::newRow("-zero") << -qfloat16(0) << FP_ZERO; QTest::newRow("one") << qfloat16(1) << FP_NORMAL; QTest::newRow("-one") << qfloat16(-1) << FP_NORMAL; QTest::newRow("ten") << qfloat16(10) << FP_NORMAL; @@ -459,6 +461,12 @@ void tst_qfloat16::limits() // See also: qNaN() and infinity() // A few useful values: const qfloat16 zero(0), one(1), ten(10); + // The specifics of minus zero: + // (IEEE 754 seems to want -zero < zero, but -0. == 0. and -0.f == 0.f in C++.) + QVERIFY(-zero <= zero); + QVERIFY(-zero == zero); + QVERIFY(!(-zero > zero)); + // digits in the mantissa, including the implicit 1 before the binary dot at its left: QVERIFY(qfloat16(1 << (Bounds::digits - 1)) + one > qfloat16(1 << (Bounds::digits - 1))); QVERIFY(qfloat16(1 << Bounds::digits) + one == qfloat16(1 << Bounds::digits)); @@ -523,7 +531,10 @@ void tst_qfloat16::limits() // See also: qNaN() and infinity() QVERIFY(Bounds::denorm_min() > zero); if (overOptimized) QEXPECT_FAIL("", "Over-optimized on ARM", Continue); - QCOMPARE(Bounds::denorm_min() / rose, zero); + QVERIFY(Bounds::denorm_min() / rose == zero); + if (overOptimized) + QEXPECT_FAIL("", "Over-optimized on ARM", Continue); + QVERIFY(-Bounds::denorm_min() / rose == -zero); } QTEST_APPLESS_MAIN(tst_qfloat16) |