diff options
author | Liang Qi <liang.qi@qt.io> | 2019-02-08 09:28:00 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2019-02-08 12:31:02 +0100 |
commit | fbfacd33be482fa3cf0aa5cffaf7006d538a2f92 (patch) | |
tree | 92da72786b3740e37004623612c4fc1c9640d30f /tests/auto/testlib/selftests/float/tst_float.cpp | |
parent | c1f4286a5cbc1794fe7be5bdbbd6a0bf29ef84d4 (diff) | |
parent | 74e04d6ace7aa949db97ae2e46c38a4dc0d4d36a (diff) |
Merge remote-tracking branch 'origin/5.12' into 5.13
Conflicts:
src/android/templates/AndroidManifest.xml
src/network/ssl/qsslsocket_mac.cpp
src/widgets/styles/qstylesheetstyle.cpp
tests/auto/corelib/kernel/qtimer/BLACKLIST
tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp
tests/auto/testlib/selftests/expected_blacklisted.lightxml
tests/auto/testlib/selftests/expected_blacklisted.tap
tests/auto/testlib/selftests/expected_blacklisted.teamcity
tests/auto/testlib/selftests/expected_blacklisted.txt
tests/auto/testlib/selftests/expected_blacklisted.xml
tests/auto/testlib/selftests/expected_blacklisted.xunitxml
tests/auto/testlib/selftests/expected_float.tap
tests/auto/testlib/selftests/expected_float.teamcity
tests/auto/testlib/selftests/expected_float.txt
tests/auto/testlib/selftests/expected_float.xunitxml
Done-With: Christian Ehrlicher <ch.ehrlicher@gmx.de>
Done-With: Edward Welbourne <edward.welbourne@qt.io>
Done-With: Timur Pocheptsov <timur.pocheptsov@qt.io>
Change-Id: If93cc432a56ae3ac1b6533d0028e4dc497415a52
Diffstat (limited to 'tests/auto/testlib/selftests/float/tst_float.cpp')
-rw-r--r-- | tests/auto/testlib/selftests/float/tst_float.cpp | 148 |
1 files changed, 129 insertions, 19 deletions
diff --git a/tests/auto/testlib/selftests/float/tst_float.cpp b/tests/auto/testlib/selftests/float/tst_float.cpp index b12bc24c58..49d00ac0e0 100644 --- a/tests/auto/testlib/selftests/float/tst_float.cpp +++ b/tests/auto/testlib/selftests/float/tst_float.cpp @@ -31,10 +31,13 @@ #include <QtTest/QtTest> #include <QDebug> +// Test proper handling of floating-point types class tst_float: public QObject { Q_OBJECT private slots: + void doubleComparisons() const; + void doubleComparisons_data() const; void floatComparisons() const; void floatComparisons_data() const; void float16Comparisons() const; @@ -43,6 +46,79 @@ private slots: void compareFloatTests_data() const; }; +void tst_float::doubleComparisons() const +{ + QFETCH(double, operandLeft); + QFETCH(double, operandRight); + + QCOMPARE(operandLeft, operandRight); +} + +void tst_float::doubleComparisons_data() const +{ + QTest::addColumn<double>("operandLeft"); + QTest::addColumn<double>("operandRight"); + + QTest::newRow("should PASS 1") << 0. << 0.; + QTest::newRow("should FAIL 1") << 1.00000 << 3.00000; + QTest::newRow("should FAIL 2") << 1.00000e-7 << 3.00000e-7; + + // QCOMPARE for doubles uses qFuzzyCompare(), which succeeds if the numbers + // differ by no more than 1e-12 times the smaller value. Thus + // QCOMPARE(1e12-2, 1e12-1) should fail, while QCOMPARE(1e12+1, 1e12+2) + // should pass. + + QTest::newRow("should PASS 2") << 1e12 + 1. << 1e12 + 2.; + QTest::newRow("should FAIL 3") << 1e12 - 1. << 1e12 - 2.; + // ... but rounding makes that a bit unrelaible when scaled close to the bounds. + QTest::newRow("should PASS 3") << 1e-310 + 1e-322 << 1e-310 + 2e-322; + QTest::newRow("should FAIL 4") << 1e-310 - 1e-322 << 1e-310 - 3e-322; + QTest::newRow("should PASS 4") << 1e307 + 1e295 << 1e307 + 2e295; + QTest::newRow("should FAIL 5") << 1e307 - 1e295 << 1e307 - 3e295; + + // QCOMPARE special-cases non-finite values + if (std::numeric_limits<double>::has_quiet_NaN) { + const double nan = std::numeric_limits<double>::quiet_NaN(); + QTest::newRow("should PASS: NaN == NaN") << nan << nan; + QTest::newRow("should FAIL: NaN != 0") << nan << 0.; + QTest::newRow("should FAIL: 0 != NaN") << 0. << nan; + QTest::newRow("should FAIL: NaN != 1") << nan << 1.; + QTest::newRow("should FAIL: 1 != NaN") << 1. << nan; + } + if (std::numeric_limits<double>::has_infinity) { + const double uge = std::numeric_limits<double>::infinity(); + QTest::newRow("should PASS: inf == inf") << uge << uge; + QTest::newRow("should PASS: -inf == -inf") << -uge << -uge; + QTest::newRow("should FAIL: inf != -inf") << uge << -uge; + QTest::newRow("should FAIL: -inf != inf") << -uge << uge; + if (std::numeric_limits<double>::has_quiet_NaN) { + const double nan = std::numeric_limits<double>::quiet_NaN(); + QTest::newRow("should FAIL: inf != nan") << uge << nan; + QTest::newRow("should FAIL: nan != inf") << nan << uge; + QTest::newRow("should FAIL: -inf != nan") << -uge << nan; + QTest::newRow("should FAIL: nan != -inf") << nan << -uge; + } + QTest::newRow("should FAIL: inf != 0") << uge << 0.; + QTest::newRow("should FAIL: 0 != inf") << 0. << uge; + QTest::newRow("should FAIL: -inf != 0") << -uge << 0.; + QTest::newRow("should FAIL: 0 != -inf") << 0. << -uge; + QTest::newRow("should FAIL: inf != 1") << uge << 1.; + QTest::newRow("should FAIL: 1 != inf") << 1. << uge; + QTest::newRow("should FAIL: -inf != 1") << -uge << 1.; + QTest::newRow("should FAIL: 1 != -inf") << 1. << -uge; + + const double big = std::numeric_limits<double>::max(); + QTest::newRow("should FAIL: inf != max") << uge << big; + QTest::newRow("should FAIL: inf != -max") << uge << -big; + QTest::newRow("should FAIL: max != inf") << big << uge; + QTest::newRow("should FAIL: -max != inf") << -big << uge; + QTest::newRow("should FAIL: -inf != max") << -uge << big; + QTest::newRow("should FAIL: -inf != -max") << -uge << -big; + QTest::newRow("should FAIL: max != -inf") << big << -uge; + QTest::newRow("should FAIL: -max != -inf") << -big << -uge; + } +} + void tst_float::floatComparisons() const { QFETCH(float, operandLeft); @@ -56,30 +132,64 @@ void tst_float::floatComparisons_data() const QTest::addColumn<float>("operandLeft"); QTest::addColumn<float>("operandRight"); - QTest::newRow("should SUCCEED 1") - << float(0) - << float(0); - - QTest::newRow("should FAIL 1") - << float(1.00000) - << float(3.00000); - - QTest::newRow("should FAIL 2") - << float(1.00000e-7f) - << float(3.00000e-7f); + QTest::newRow("should FAIL 1") << 1.00000f << 3.00000f; + QTest::newRow("should PASS 1") << 0.f << 0.f; + QTest::newRow("should FAIL 2") << 1.00000e-7f << 3.00000e-7f; // QCOMPARE for floats uses qFuzzyCompare(), which succeeds if the numbers - // differ by no more than 1/100,000th of the smaller value. Thus - // QCOMPARE(99998, 99999) should fail, while QCOMPARE(100001, 100002) + // differ by no more than 1e-5 times the smaller value. Thus + // QCOMPARE(1e5-2, 1e5-1) should fail, while QCOMPARE(1e5+1, 1e5+2) // should pass. - QTest::newRow("should FAIL 3") - << float(99998) - << float(99999); + QTest::newRow("should PASS 2") << 1e5f + 1.f << 1e5f + 2.f; + QTest::newRow("should FAIL 3") << 1e5f - 1.f << 1e5f - 2.f; + // ... but rounding makes that a bit unrelaible when scaled close to the bounds. + QTest::newRow("should PASS 3") << 1e-39f + 1e-44f << 1e-39f + 2e-44f; + QTest::newRow("should FAIL 4") << 1e-39f - 1e-44f << 1e-39f - 3e-44f; + QTest::newRow("should PASS 4") << 1e38f + 1e33f << 1e38f + 2e33f; + QTest::newRow("should FAIL 5") << 1e38f - 1e33f << 1e38f - 3e33f; - QTest::newRow("should SUCCEED 2") - << float(100001) - << float(100002); + // QCOMPARE special-cases non-finite values + if (std::numeric_limits<float>::has_quiet_NaN) { + const float nan = std::numeric_limits<float>::quiet_NaN(); + QTest::newRow("should PASS: NaN == NaN") << nan << nan; + QTest::newRow("should FAIL: NaN != 0") << nan << 0.f; + QTest::newRow("should FAIL: 0 != NaN") << 0.f << nan; + QTest::newRow("should FAIL: NaN != 1") << nan << 1.f; + QTest::newRow("should FAIL: 1 != NaN") << 1.f << nan; + } + if (std::numeric_limits<float>::has_infinity) { + const float uge = std::numeric_limits<float>::infinity(); + QTest::newRow("should PASS: inf == inf") << uge << uge; + QTest::newRow("should PASS: -inf == -inf") << -uge << -uge; + QTest::newRow("should FAIL: inf != -inf") << uge << -uge; + QTest::newRow("should FAIL: -inf != inf") << -uge << uge; + if (std::numeric_limits<float>::has_quiet_NaN) { + const float nan = std::numeric_limits<float>::quiet_NaN(); + QTest::newRow("should FAIL: inf != nan") << uge << nan; + QTest::newRow("should FAIL: nan != inf") << nan << uge; + QTest::newRow("should FAIL: -inf != nan") << -uge << nan; + QTest::newRow("should FAIL: nan != -inf") << nan << -uge; + } + QTest::newRow("should FAIL: inf != 0") << uge << 0.f; + QTest::newRow("should FAIL: 0 != inf") << 0.f << uge; + QTest::newRow("should FAIL: -inf != 0") << -uge << 0.f; + QTest::newRow("should FAIL: 0 != -inf") << 0.f << -uge; + QTest::newRow("should FAIL: inf != 1") << uge << 1.f; + QTest::newRow("should FAIL: 1 != inf") << 1.f << uge; + QTest::newRow("should FAIL: -inf != 1") << -uge << 1.f; + QTest::newRow("should FAIL: 1 != -inf") << 1.f << -uge; + + const float big = std::numeric_limits<float>::max(); + QTest::newRow("should FAIL: inf != max") << uge << big; + QTest::newRow("should FAIL: inf != -max") << uge << -big; + QTest::newRow("should FAIL: max != inf") << big << uge; + QTest::newRow("should FAIL: -max != inf") << -big << uge; + QTest::newRow("should FAIL: -inf != max") << -uge << big; + QTest::newRow("should FAIL: -inf != -max") << -uge << -big; + QTest::newRow("should FAIL: max != -inf") << big << -uge; + QTest::newRow("should FAIL: -max != -inf") << -big << -uge; + } } void tst_float::float16Comparisons() const |