summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2018-11-19 19:53:38 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2018-11-23 10:05:24 +0000
commitce159d1a3e48308d54300560f024e8501c1395c9 (patch)
tree5893e5b235738b6abfb6352d6cdf5f1f2e9cada9 /tests
parenta9923674030980706940b3ee11145c38674bb35d (diff)
Fix toFloat()s between float and double ranges and document
Revised some toFloat()s to be consistent with the matching toDouble()s; previously, they would return infinity if toDouble() did but return 0 if toDouble() got a finite value outside float's range. That also applied to values that underflowed float's range, succeeding and returning 0 as long as they were within double's range but failing if toDouble() underflowed. Now float-underflow also fails. Amended their documentation to reflect this more consistent reality. Added some tests of out-of-range values, infinities and NaNs. [ChangeLog][QtCore][toFloat] QString, QByteArray and QLocale returned an infinity on double-overflow (since 5.7) but returned 0 on a finite double outside float's range, while setting ok to false; this was at odds with their documented behavior of returning 0 on any failure. They also succeeded, returning zero, on underflow of float's range, unless double underflowed, where they failed. Changed the handling of values outside float's range to match that of values outside double's range: fail, returning an infinity on overflow or zero on underflow. The documentation now reflects the revised behavior, which matches toDouble(). Change-Id: Ia168bcacf7def0df924840d45d8edc5f850449d6 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp42
1 files changed, 32 insertions, 10 deletions
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
index 7bf6d1327e..b8f1cc568a 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -877,6 +877,28 @@ void tst_QLocale::stringToDouble()
void tst_QLocale::stringToFloat_data()
{
toReal_data();
+ if (std::numeric_limits<float>::has_infinity) {
+ double huge = std::numeric_limits<float>::infinity();
+ QTest::newRow("C inf") << QString("C") << QString("inf") << true << huge;
+ QTest::newRow("C +inf") << QString("C") << QString("+inf") << true << +huge;
+ QTest::newRow("C -inf") << QString("C") << QString("-inf") << true << -huge;
+ // Overflow float, but not double:
+ QTest::newRow("C big") << QString("C") << QString("3.5e38") << false << huge;
+ QTest::newRow("C -big") << QString("C") << QString("-3.5e38") << false << -huge;
+ // Overflow double, too:
+ QTest::newRow("C huge") << QString("C") << QString("2e308") << false << huge;
+ QTest::newRow("C -huge") << QString("C") << QString("-2e308") << false << -huge;
+ }
+ if (std::numeric_limits<float>::has_quiet_NaN)
+ QTest::newRow("C qnan") << QString("C") << QString("NaN") << true << double(std::numeric_limits<float>::quiet_NaN());
+
+ // Underflow float, but not double:
+ QTest::newRow("C small") << QString("C") << QString("1e-45") << false << 0.;
+ QTest::newRow("C -small") << QString("C") << QString("-1e-45") << false << 0.;
+
+ // Underflow double, too:
+ QTest::newRow("C tiny") << QString("C") << QString("2e-324") << false << 0.;
+ QTest::newRow("C -tiny") << QString("C") << QString("-2e-324") << false << 0.;
}
void tst_QLocale::stringToFloat()
@@ -904,24 +926,24 @@ void tst_QLocale::stringToFloat()
QCOMPARE(ok, good);
}
- if (ok) {
+ if (ok || std::isinf(fnum)) {
// First use fuzzy-compare, then a more precise check:
QCOMPARE(f, fnum);
- float diff = f - fnum;
- if (diff < 0)
- diff = -diff;
- QVERIFY(diff <= MY_FLOAT_EPSILON);
+ if (std::isfinite(fnum)) {
+ float diff = f > fnum ? f - fnum : fnum - f;
+ QVERIFY(diff <= MY_FLOAT_EPSILON);
+ }
}
f = locale.toFloat(num_strRef, &ok);
QCOMPARE(ok, good);
- if (ok) {
+ if (ok || std::isinf(fnum)) {
QCOMPARE(f, fnum);
- float diff = f - fnum;
- if (diff < 0)
- diff = -diff;
- QVERIFY(diff <= MY_FLOAT_EPSILON);
+ if (std::isfinite(fnum)) {
+ float diff = f > fnum ? f - fnum : fnum - f;
+ QVERIFY(diff <= MY_FLOAT_EPSILON);
+ }
}
#undef MY_FLOAT_EPSILON
}