From 7bf4f81de81b6e800509867d5acad545c566dbac Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 17 Sep 2019 19:53:55 +0200 Subject: Add qfloat16::copySign() since we can't overload std::copysign() Change-Id: Idfaf841b3eb3538f076ae4f0de2d7d029e1588fe Reviewed-by: Thiago Macieira --- src/corelib/global/qfloat16.cpp | 8 ++++++++ src/corelib/global/qfloat16.h | 3 +++ tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp | 11 ++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp index 6c21b7de5a..97709d7685 100644 --- a/src/corelib/global/qfloat16.cpp +++ b/src/corelib/global/qfloat16.cpp @@ -145,6 +145,14 @@ QT_BEGIN_NAMESPACE \sa qIsFinite() */ +/*! + \since 5.15 + \fn qfloat16::copySign(qfloat16 sign) const noexcept + + Returns a qfloat16 with the sign of \a sign but the rest of its value taken + from this qfloat16. Serves as qfloat16's equivalent of std::copysign(). +*/ + /*! \internal \since 5.14 diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h index 9a4f1800a4..c50fa36402 100644 --- a/src/corelib/global/qfloat16.h +++ b/src/corelib/global/qfloat16.h @@ -84,6 +84,9 @@ public: bool isNaN() const noexcept { return ((b16 >> 8) & 0x7e) == 0x7e; } bool isFinite() const noexcept { return ((b16 >> 8) & 0x7c) != 0x7c; } Q_CORE_EXPORT int fpClassify() const noexcept; + // Can't specialize std::copysign() for qfloat16 + qfloat16 copySign(qfloat16 sign) const noexcept + { return qfloat16(Wrap((sign.b16 & 0x8000) | (b16 & 0x7fff))); } // Support for std::numeric_limits static constexpr qfloat16 _limit_epsilon() noexcept { return qfloat16(Wrap(0x1400)); } static constexpr qfloat16 _limit_min() noexcept { return qfloat16(Wrap(0x400)); } diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp index 94f0afa5ed..a661b0388e 100644 --- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp +++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp @@ -430,6 +430,13 @@ void tst_qfloat16::finite() QVERIFY(!qIsInf(value)); QVERIFY(!qIsNaN(value)); QCOMPARE(qFpClassify(value), mode); + + // *NOT* using QCOMPARE() on finite qfloat16 values, since that uses fuzzy + // comparison, and we need exact here. + const qfloat16 zero(0), plus(+1), minus(-1); + const qfloat16 magnitude = (value < zero) ? -value : value; + QVERIFY(value.copySign(plus) == magnitude); + QVERIFY(value.copySign(minus) == -magnitude); } void tst_qfloat16::properties() @@ -534,7 +541,9 @@ void tst_qfloat16::limits() // See also: qNaN() and infinity() QVERIFY(Bounds::denorm_min() / rose == zero); if (overOptimized) QEXPECT_FAIL("", "Over-optimized on ARM", Continue); - QVERIFY(-Bounds::denorm_min() / rose == -zero); + const qfloat16 under = (-Bounds::denorm_min()) / rose; + QVERIFY(under == -zero); + QCOMPARE(qfloat16(1).copySign(under), qfloat16(-1)); } QTEST_APPLESS_MAIN(tst_qfloat16) -- cgit v1.2.3