Add tests for qFuzzyIsNull() to tst_QNumeric and tst_QFloat16

They were missing.
I also wanted to verify that it's true for sub-normal values.

At the same time, relocate qfloat16's implementation of qFuzzyIsNull()
to between those of qFuzzyCompare() and qIsNull(), since its apparent
absence initially confused me.

Change-Id: I9637c0070e754d16744c76fc9f846596257c6a63
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2020-04-15 18:31:51 +02:00
parent 16c9683718
commit 6dfec83051
4 changed files with 77 additions and 10 deletions

View File

@ -234,6 +234,14 @@ Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qsizetype length
return (qAbs(f1 - f2) * 102.5f <= qMin(qAbs(f1), qAbs(f2)));
}
/*!
\internal
*/
[[nodiscard]] inline bool qFuzzyIsNull(qfloat16 f) noexcept
{
return qAbs(static_cast<float>(f)) <= 0.001f;
}
[[nodiscard]] inline bool qIsNull(qfloat16 f) noexcept
{
return (f.b16 & static_cast<quint16>(0x7fff)) == 0;
@ -300,14 +308,6 @@ inline qfloat16::operator float() const noexcept
}
#endif
/*!
\internal
*/
[[nodiscard]] inline bool qFuzzyIsNull(qfloat16 f) noexcept
{
return qAbs(static_cast<float>(f)) <= 0.001f;
}
/*
qHypot compatibility; see ../kernel/qmath.h
*/

View File

@ -7,4 +7,6 @@
qt_internal_add_test(tst_qfloat16
SOURCES
tst_qfloat16.cpp
PUBLIC_LIBRARIES
Qt::TestPrivate
)

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2016 by Southwest Research Institute (R)
** Contact: https://www.qt.io/licensing/
**
@ -43,6 +43,8 @@ class tst_qfloat16: public QObject
private slots:
void fuzzyCompare_data();
void fuzzyCompare();
void fuzzyIsNull_data();
void fuzzyIsNull();
void ltgt_data();
void ltgt();
void qNaN();
@ -111,6 +113,33 @@ void tst_qfloat16::fuzzyCompare()
}
}
void tst_qfloat16::fuzzyIsNull_data()
{
QTest::addColumn<qfloat16>("value");
QTest::addColumn<bool>("isNull");
using Bounds = std::numeric_limits<qfloat16>;
const qfloat16 one(1), huge(1000), tiny(0.00099f);
QTest::newRow("zero") << qfloat16(0.0f) << true;
QTest::newRow("min") << Bounds::min() << true;
QTest::newRow("denorm_min") << Bounds::denorm_min() << true;
QTest::newRow("tiny") << tiny << true;
QTest::newRow("deci") << qfloat16(.1) << false;
QTest::newRow("one") << one << false;
QTest::newRow("ten") << qfloat16(10) << false;
QTest::newRow("huge") << huge << false;
}
void tst_qfloat16::fuzzyIsNull()
{
QFETCH(qfloat16, value);
QFETCH(bool, isNull);
QCOMPARE(::qFuzzyIsNull(value), isNull);
QCOMPARE(::qFuzzyIsNull(-value), isNull);
}
void tst_qfloat16::ltgt_data()
{
QTest::addColumn<float>("val1");

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@ -52,6 +52,8 @@ class tst_QNumeric: public QObject
// Support for floating-point:
template<typename F> inline void fuzzyCompare_data();
template<typename F> inline void fuzzyCompare();
template<typename F> inline void fuzzyIsNull_data();
template<typename F> inline void fuzzyIsNull();
template<typename F> inline void checkNaN(F nan);
template<typename F> inline void rawNaN_data();
template<typename F> inline void rawNaN();
@ -71,6 +73,10 @@ private slots:
void fuzzyCompareF() { fuzzyCompare<float>(); }
void fuzzyCompareD_data() { fuzzyCompare_data<double>(); }
void fuzzyCompareD() { fuzzyCompare<double>(); }
void fuzzyIsNullF_data() { fuzzyIsNull_data<float>(); }
void fuzzyIsNullF() { fuzzyIsNull<float>(); }
void fuzzyIsNullD_data() { fuzzyIsNull_data<double>(); }
void fuzzyIsNullD() { fuzzyIsNull<double>(); }
void rawNaNF_data() { rawNaN_data<float>(); }
void rawNaNF() { rawNaN<float>(); }
void rawNaND_data() { rawNaN_data<double>(); }
@ -143,6 +149,36 @@ void tst_QNumeric::fuzzyCompare()
QCOMPARE(::qFuzzyCompare(-val2, -val1), isEqual);
}
template<typename F>
void tst_QNumeric::fuzzyIsNull_data()
{
QTest::addColumn<F>("value");
QTest::addColumn<bool>("isNull");
using Bounds = std::numeric_limits<F>;
const F one(1), huge = Fuzzy<F>::scale, tiny = one / huge;
QTest::newRow("zero") << F(0) << true;
QTest::newRow("min") << Bounds::min() << true;
QTest::newRow("denorm_min") << Bounds::denorm_min() << true;
QTest::newRow("tiny") << tiny << true;
QTest::newRow("deci") << F(.1) << false;
QTest::newRow("one") << one << false;
QTest::newRow("ten") << F(10) << false;
QTest::newRow("large") << F(1e9) << false;
QTest::newRow("huge") << huge << false;
}
template<typename F>
void tst_QNumeric::fuzzyIsNull()
{
QFETCH(F, value);
QFETCH(bool, isNull);
QCOMPARE(::qFuzzyIsNull(value), isNull);
QCOMPARE(::qFuzzyIsNull(-value), isNull);
}
#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)
// turn -ffast-math off
# pragma GCC optimize "no-fast-math"