QVariant: make sure two floating points compare equal if they are equal

Not just fuzzily equal. The fuzzy comparison fails for infinities, since
the expression p1 - p2 where p1 = p2 = infinity is NaN. And NaN
comparisons are always false.

As a nice side-effect, we don't do the more expensive computation of a
multiplication if the two numbers really are equal.

Task-number: QTBUG-50036
Change-Id: I11f559ef75544c50b3f8ffff1420cec7c7273295
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
bb10
Thiago Macieira 2015-12-17 13:07:17 -08:00
parent 29f41e5e38
commit ac2bde9caf
2 changed files with 8 additions and 1 deletions

View File

@ -3448,7 +3448,7 @@ static int numericCompare(const QVariant::Private *d1, const QVariant::Private *
Q_ASSERT(ok);
qreal r2 = qConvertToRealNumber(d2, &ok);
Q_ASSERT(ok);
if (qFuzzyCompare(r1, r2))
if (r1 == r2 || qFuzzyCompare(r1, r2))
return 0;
return r1 < r2 ? -1 : 1;
}

View File

@ -1711,12 +1711,16 @@ void tst_QVariant::compareNumbers_data() const
QTest::newRow("float3") << qVariantFromValue(0.f) << qVariantFromValue(-1.f) << +1;
QTest::newRow("float4") << qVariantFromValue(-float(qInf())) << qVariantFromValue(0.f) << -1;
QTest::newRow("float5") << qVariantFromValue(0.f) << qVariantFromValue(-float(qInf())) << +1;
QTest::newRow("float6") << qVariantFromValue(-float(qInf())) << qVariantFromValue(-float(qInf())) << 0;
QTest::newRow("float7") << qVariantFromValue(float(qInf())) << qVariantFromValue(float(qInf())) << 0;
QTest::newRow("double1") << qVariantFromValue(0.) << qVariantFromValue(0.) << 0;
QTest::newRow("double2") << qVariantFromValue(-1.) << qVariantFromValue(0.) << -1;
QTest::newRow("double3") << qVariantFromValue(0.) << qVariantFromValue(-1.) << +1;
QTest::newRow("double4") << qVariantFromValue(-qInf()) << qVariantFromValue(0.) << -1;
QTest::newRow("double5") << qVariantFromValue(0.) << qVariantFromValue(-qInf()) << +1;
QTest::newRow("double6") << qVariantFromValue(-double(qInf())) << qVariantFromValue(-qInf()) << 0;
QTest::newRow("double7") << qVariantFromValue(qInf()) << qVariantFromValue(qInf()) << 0;
// mixed comparisons
// fp + fp
@ -1725,6 +1729,8 @@ void tst_QVariant::compareNumbers_data() const
QTest::newRow("float+double3") << qVariantFromValue(0.f) << qVariantFromValue(-1.) << +1;
QTest::newRow("float+double4") << qVariantFromValue(-float(qInf())) << qVariantFromValue(0.) << -1;
QTest::newRow("float+double5") << qVariantFromValue(0.f) << qVariantFromValue(-qInf()) << +1;
QTest::newRow("float+double6") << qVariantFromValue(-float(qInf())) << qVariantFromValue(qInf()) << 0;
QTest::newRow("float+double7") << qVariantFromValue(float(qInf())) << qVariantFromValue(qInf()) << 0;
// fp + int
QTest::newRow("float+int1") << qVariantFromValue(0.f) << qVariantFromValue(0) << 0;
@ -1735,6 +1741,7 @@ void tst_QVariant::compareNumbers_data() const
QTest::newRow("double+int3") << qVariantFromValue(0.) << qVariantFromValue(-1) << +1;
QTest::newRow("float+int4") << qVariantFromValue(1.5f) << qVariantFromValue(1) << +1;
QTest::newRow("double+int4") << qVariantFromValue(1.5) << qVariantFromValue(1) << +1;
QTest::newRow("double+int5") << qVariantFromValue(qInf()) << qVariantFromValue(1) << +1;
// fp + uint
QTest::newRow("float+uint1") << qVariantFromValue(0.f) << qVariantFromValue(0U) << 0;