QVariant: don't do fuzzy comparisons with NaN and infinities
There was a test that tested this, but was wrong. [ChangeLog][QtCore][QVariant] Fixed a bug that caused wrong results for comparisons of QVariants containing either NaN or infinite numbers. Task-number: QTBUG-56073 Change-Id: I33dc971f005a4848bb8ffffd1475d29d00dd1b7f Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
9369eca108
commit
14f0964344
@ -74,6 +74,7 @@
|
||||
#include "qline.h"
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#include <float.h>
|
||||
#include <cstring>
|
||||
|
||||
@ -3472,8 +3473,17 @@ static int numericCompare(const QVariant::Private *d1, const QVariant::Private *
|
||||
Q_ASSERT(ok);
|
||||
qreal r2 = qConvertToRealNumber(d2, &ok);
|
||||
Q_ASSERT(ok);
|
||||
if (r1 == r2 || qFuzzyCompare(r1, r2))
|
||||
if (r1 == r2)
|
||||
return 0;
|
||||
|
||||
// only do fuzzy comparisons for finite, non-zero numbers
|
||||
int c1 = std::fpclassify(r1);
|
||||
int c2 = std::fpclassify(r2);
|
||||
if ((c1 == FP_NORMAL || c1 == FP_SUBNORMAL) && (c2 == FP_NORMAL || c2 == FP_SUBNORMAL)) {
|
||||
if (qFuzzyCompare(r1, r2))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return r1 < r2 ? -1 : 1;
|
||||
}
|
||||
|
||||
|
@ -1755,6 +1755,10 @@ void tst_QVariant::compareNumbers_data() const
|
||||
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;
|
||||
QTest::newRow("double8") << qVariantFromValue(-qInf()) << qVariantFromValue(qInf()) << -1;
|
||||
QTest::newRow("double9") << qVariantFromValue(qQNaN()) << qVariantFromValue(0.) << INT_MAX;
|
||||
QTest::newRow("double10") << qVariantFromValue(0.) << qVariantFromValue(qQNaN()) << INT_MAX;
|
||||
QTest::newRow("double11") << qVariantFromValue(qQNaN()) << qVariantFromValue(qQNaN()) << INT_MAX;
|
||||
|
||||
// mixed comparisons
|
||||
// fp + fp
|
||||
@ -1763,8 +1767,12 @@ 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+double6") << qVariantFromValue(-float(qInf())) << qVariantFromValue(-qInf()) << 0;
|
||||
QTest::newRow("float+double7") << qVariantFromValue(float(qInf())) << qVariantFromValue(qInf()) << 0;
|
||||
QTest::newRow("float+double8") << qVariantFromValue(-float(qInf())) << qVariantFromValue(qInf()) << -1;
|
||||
QTest::newRow("float+double9") << qVariantFromValue(qQNaN()) << qVariantFromValue(0.) << INT_MAX;
|
||||
QTest::newRow("float+double10") << qVariantFromValue(0.) << qVariantFromValue(qQNaN()) << INT_MAX;
|
||||
QTest::newRow("float+double11") << qVariantFromValue(qQNaN()) << qVariantFromValue(qQNaN()) << INT_MAX;
|
||||
|
||||
// fp + int
|
||||
QTest::newRow("float+int1") << qVariantFromValue(0.f) << qVariantFromValue(0) << 0;
|
||||
@ -1978,7 +1986,7 @@ void tst_QVariant::compareNumbers() const
|
||||
QCOMPARE(v2, v1);
|
||||
QVERIFY(v2 >= v1);
|
||||
QVERIFY(!(v2 > v1));
|
||||
} else {
|
||||
} else if (expected == +1) {
|
||||
QVERIFY(!(v1 < v2));
|
||||
QVERIFY(!(v1 <= v2));
|
||||
QVERIFY(!(v1 == v2));
|
||||
@ -1990,6 +1998,9 @@ void tst_QVariant::compareNumbers() const
|
||||
QVERIFY(!(v2 == v1));
|
||||
QVERIFY(!(v2 >= v1));
|
||||
QVERIFY(!(v2 > v1));
|
||||
} else {
|
||||
// unorderable (NaN)
|
||||
QVERIFY(!(v1 == v2));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user