Use qFuzzyCompare instead of qFuzzyIsNull in QPointF ==

qFuzzyIsNull has a fixed range, where qFuzzyCompare can tell if numbers
are different in a more relative range. Without it QPointFs that are
heavily scaled will be interpreted as identical, when they are quite
different at their own scale.

Task-number: QTBUG-60359
Task-number: QTBUG-62161
Change-Id: Ic4ba90e9e994aedff5548d690f053eb309b0a60b
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Allan Sandfeld Jensen 2018-04-23 13:46:55 +02:00
parent 6a14608742
commit d517d5428c
2 changed files with 49 additions and 2 deletions

View File

@ -345,16 +345,24 @@ Q_DECL_RELAXED_CONSTEXPR inline QPointF &QPointF::operator*=(qreal c)
xp*=c; yp*=c; return *this;
}
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
Q_DECL_CONSTEXPR inline bool operator==(const QPointF &p1, const QPointF &p2)
{
return qFuzzyIsNull(p1.xp - p2.xp) && qFuzzyIsNull(p1.yp - p2.yp);
return ((!p1.xp && !p1.yp) || (!p2.xp && !p2.yp))
? (qFuzzyIsNull(p1.xp - p2.xp) && qFuzzyIsNull(p1.yp - p2.yp))
: (qFuzzyCompare(p1.xp, p2.xp) && qFuzzyCompare(p1.yp, p2.yp));
}
Q_DECL_CONSTEXPR inline bool operator!=(const QPointF &p1, const QPointF &p2)
{
return !qFuzzyIsNull(p1.xp - p2.xp) || !qFuzzyIsNull(p1.yp - p2.yp);
return !(p1 == p2);
}
QT_WARNING_POP
Q_DECL_CONSTEXPR inline const QPointF operator+(const QPointF &p1, const QPointF &p2)
{
return QPointF(p1.xp+p2.xp, p1.yp+p2.yp);

View File

@ -77,6 +77,8 @@ private slots:
void toPoint_data();
void toPoint();
void compare();
#ifndef QT_NO_DATASTREAM
void stream_data();
void stream();
@ -413,5 +415,42 @@ void tst_QPointF::stream()
}
#endif
void tst_QPointF::compare()
{
// First test we can scale and maintain difference.
QPointF p1(2.0, 2.0);
QPointF p2(3.0, 3.0);
QVERIFY(p1 != p2);
p1 /= 1e5;
p2 /= 1e5;
QVERIFY(!(p1 == p2));
p1 /= 1e5;
p2 /= 1e5;
QVERIFY(p1 != p2);
p1 /= 1e5;
p2 /= 1e5;
QVERIFY(!(p1 == p2));
p1 /= 2;
p2 /= 3;
QVERIFY(p1 == p2);
// Test we can compare with zero after inexact math
QPointF p3(3.0, 3.0);
p3 *= 0.1;
p3 /= 3;
p3 -= QPointF(0.1, 0.1);
QVERIFY(p3 == QPointF());
}
QTEST_MAIN(tst_QPointF)
#include "tst_qpointf.moc"