From 9bad096c091b2c2106c2f325dfca74be111eee58 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 15 Apr 2021 17:47:05 +0200 Subject: [PATCH] Use a more forgiving threshold for qFuzzyIsNull(qfloat16) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Analysis of problems with the new test for qFuzzyIsNull() revealed that, where its version for double uses approximately 4500 * epsilon and for float used 84 * epsilon as threshold, the qfloat16 version's value was barely more than epsilon, with the result that the test had to use a different value than the threshold to pass. (Converting the threshold from float to qfloat16 and back made it bigger; in effect, the threshold value was not <= itself.) Furthermore, comparison with qFuzzyCompare() implied a value of 1/102.5 should be used, roughly 10 * epsilon, for consistency. When 1/102.5 is rounded to three significant digits (the precision we use in QTest::toString(), for example), to give 0.00976f as threshold, we get a value that, after conversion to qfloat16 and back to float, does give a result <= what we started with. So change qFuzzyIsNull() and its test to use this as qfloat16's threshold value. [ChangeLog][QtCore][QFloat16] The qfloat16 threshold value for qFuzzyIsNull() has changed from 1e-3 to 9.76e-3, almost a factor of ten increase, for consistency with qFuzzyCompare()'s tolerance. Values between these would previously have had qFuzzyIsNull(f) false despite qFuzzyCompre(f, 1+f) being true. Change-Id: I35816dce78da34a3e2339c8bc42d5bd03714a3f6 Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Andreas Buhr Reviewed-by: Thiago Macieira --- src/corelib/global/qfloat16.h | 2 +- tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h index e574ffed78..c2e5379eb4 100644 --- a/src/corelib/global/qfloat16.h +++ b/src/corelib/global/qfloat16.h @@ -239,7 +239,7 @@ Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qsizetype length */ [[nodiscard]] inline bool qFuzzyIsNull(qfloat16 f) noexcept { - return qAbs(static_cast(f)) <= 0.001f; + return qAbs(f) < 0.00976f; // 1/102.5 to 3 significant digits; see qFuzzyCompare() } [[nodiscard]] inline bool qIsNull(qfloat16 f) noexcept diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp index 71a05d3031..35d7dbccf0 100644 --- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp +++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp @@ -118,7 +118,7 @@ void tst_qfloat16::fuzzyIsNull_data() QTest::addColumn("value"); QTest::addColumn("isNull"); using Bounds = std::numeric_limits; - const qfloat16 one(1), huge(1000), tiny(0.00099f); + const qfloat16 one(1), huge(1000), tiny(0.00976f); QTest::newRow("zero") << qfloat16(0.0f) << true; QTest::newRow("min") << Bounds::min() << true;