Add qfloat16::copySign() since we can't overload std::copysign()

Change-Id: Idfaf841b3eb3538f076ae4f0de2d7d029e1588fe
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2019-09-17 19:53:55 +02:00
parent b7858e9b4b
commit 7bf4f81de8
3 changed files with 21 additions and 1 deletions

View File

@ -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

View File

@ -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<qfloat16>
static constexpr qfloat16 _limit_epsilon() noexcept { return qfloat16(Wrap(0x1400)); }
static constexpr qfloat16 _limit_min() noexcept { return qfloat16(Wrap(0x400)); }

View File

@ -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)