Skip to content

Commit

Permalink
Add qfloat16::copySign() since we can't overload std::copysign()
Browse files Browse the repository at this point in the history
Change-Id: Idfaf841b3eb3538f076ae4f0de2d7d029e1588fe
Reviewed-by: Thiago Macieira <[email protected]>
  • Loading branch information
ediosyncratic committed Nov 6, 2019
1 parent b7858e9 commit 7bf4f81
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/corelib/global/qfloat16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/corelib/global/qfloat16.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ class qfloat16
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)); }
Expand Down
11 changes: 10 additions & 1 deletion tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 7bf4f81

Please sign in to comment.