Do not consider sign in qIsNull.
The current implementation of qIsNull only returns true if the value is positive zero. This behaviour is not useful for use cases like QPointF::isNull, where QPointF(-0, -0).isNull() will return false. There doesn't seem to be a reason why the function exhibits this behaviour (-0.0 is not accounted for in the unit tests), and for the case of QSizeF::scale it causes a bug: qIsNull is used to check for division by 0.0 before it proceeds, which fails in the case of -0.0. Task-number: QTBUG-7303 Change-Id: I767e5280bd26614e8e78ae62b274eb9bc4ade385 Reviewed-by: Lars Knoll <lars.knoll@nokia.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
This commit is contained in:
parent
7f469ef4cc
commit
09dd19df5c
@ -813,7 +813,7 @@ Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(float f)
|
|||||||
/*
|
/*
|
||||||
This function tests a double for a null value. It doesn't
|
This function tests a double for a null value. It doesn't
|
||||||
check whether the actual value is 0 or close to 0, but whether
|
check whether the actual value is 0 or close to 0, but whether
|
||||||
it is binary 0.
|
it is binary 0, disregarding sign.
|
||||||
*/
|
*/
|
||||||
static inline bool qIsNull(double d)
|
static inline bool qIsNull(double d)
|
||||||
{
|
{
|
||||||
@ -823,13 +823,13 @@ static inline bool qIsNull(double d)
|
|||||||
};
|
};
|
||||||
U val;
|
U val;
|
||||||
val.d = d;
|
val.d = d;
|
||||||
return val.u == quint64(0);
|
return (val.u & Q_UINT64_C(0x7fffffffffffffff)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This function tests a float for a null value. It doesn't
|
This function tests a float for a null value. It doesn't
|
||||||
check whether the actual value is 0 or close to 0, but whether
|
check whether the actual value is 0 or close to 0, but whether
|
||||||
it is binary 0.
|
it is binary 0, disregarding sign.
|
||||||
*/
|
*/
|
||||||
static inline bool qIsNull(float f)
|
static inline bool qIsNull(float f)
|
||||||
{
|
{
|
||||||
@ -839,7 +839,7 @@ static inline bool qIsNull(float f)
|
|||||||
};
|
};
|
||||||
U val;
|
U val;
|
||||||
val.f = f;
|
val.f = f;
|
||||||
return val.u == 0u;
|
return (val.u & 0x7fffffff) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -72,6 +72,12 @@ void tst_QGlobal::qIsNull()
|
|||||||
|
|
||||||
QVERIFY(!::qIsNull(d));
|
QVERIFY(!::qIsNull(d));
|
||||||
QVERIFY(!::qIsNull(f));
|
QVERIFY(!::qIsNull(f));
|
||||||
|
|
||||||
|
d = -0.0;
|
||||||
|
f = -0.0f;
|
||||||
|
|
||||||
|
QVERIFY(::qIsNull(d));
|
||||||
|
QVERIFY(::qIsNull(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QGlobal::for_each()
|
void tst_QGlobal::for_each()
|
||||||
|
@ -111,6 +111,11 @@ void tst_QPointF::isNull()
|
|||||||
QVERIFY(!point.isNull());
|
QVERIFY(!point.isNull());
|
||||||
point.rx() -= 2;
|
point.rx() -= 2;
|
||||||
QVERIFY(!point.isNull());
|
QVERIFY(!point.isNull());
|
||||||
|
|
||||||
|
QPointF nullNegativeZero(qreal(-0.0), qreal(-0.0));
|
||||||
|
QCOMPARE(nullNegativeZero.x(), (qreal)-0.0f);
|
||||||
|
QCOMPARE(nullNegativeZero.y(), (qreal)-0.0f);
|
||||||
|
QVERIFY(nullNegativeZero.isNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QPointF::manhattanLength_data()
|
void tst_QPointF::manhattanLength_data()
|
||||||
|
@ -48,6 +48,9 @@ class tst_QSizeF : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
|
void isNull_data();
|
||||||
|
void isNull();
|
||||||
|
|
||||||
void scale();
|
void scale();
|
||||||
|
|
||||||
void expandedTo();
|
void expandedTo();
|
||||||
@ -60,6 +63,34 @@ private slots:
|
|||||||
void transpose();
|
void transpose();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void tst_QSizeF::isNull_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<qreal>("width");
|
||||||
|
QTest::addColumn<qreal>("height");
|
||||||
|
QTest::addColumn<bool>("isNull");
|
||||||
|
|
||||||
|
QTest::newRow("0, 0") << qreal(0.0) << qreal(0.0) << true;
|
||||||
|
QTest::newRow("-0, -0") << qreal(-0.0) << qreal(-0.0) << true;
|
||||||
|
QTest::newRow("0, -0") << qreal(0) << qreal(-0.0) << true;
|
||||||
|
QTest::newRow("-0, 0") << qreal(-0.0) << qreal(0) << true;
|
||||||
|
QTest::newRow("-0.1, 0") << qreal(-0.1) << qreal(0) << false;
|
||||||
|
QTest::newRow("0, -0.1") << qreal(0) << qreal(-0.1) << false;
|
||||||
|
QTest::newRow("0.1, 0") << qreal(0.1) << qreal(0) << false;
|
||||||
|
QTest::newRow("0, 0.1") << qreal(0) << qreal(0.1) << false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QSizeF::isNull()
|
||||||
|
{
|
||||||
|
QFETCH(qreal, width);
|
||||||
|
QFETCH(qreal, height);
|
||||||
|
QFETCH(bool, isNull);
|
||||||
|
|
||||||
|
QSizeF size(width, height);
|
||||||
|
QCOMPARE(size.width(), width);
|
||||||
|
QCOMPARE(size.height(), height);
|
||||||
|
QCOMPARE(size.isNull(), isNull);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QSizeF::scale() {
|
void tst_QSizeF::scale() {
|
||||||
QSizeF t1(10.4, 12.8);
|
QSizeF t1(10.4, 12.8);
|
||||||
t1.scale(60.6, 60.6, Qt::IgnoreAspectRatio);
|
t1.scale(60.6, 60.6, Qt::IgnoreAspectRatio);
|
||||||
|
@ -116,6 +116,13 @@ void tst_QQuaternion::create()
|
|||||||
QCOMPARE(identity.scalar(), (qreal)1.0f);
|
QCOMPARE(identity.scalar(), (qreal)1.0f);
|
||||||
QVERIFY(identity.isIdentity());
|
QVERIFY(identity.isIdentity());
|
||||||
|
|
||||||
|
QQuaternion negativeZeroIdentity(qreal(1.0), qreal(-0.0), qreal(-0.0), qreal(-0.0));
|
||||||
|
QCOMPARE(negativeZeroIdentity.x(), qreal(-0.0));
|
||||||
|
QCOMPARE(negativeZeroIdentity.y(), qreal(-0.0));
|
||||||
|
QCOMPARE(negativeZeroIdentity.z(), qreal(-0.0));
|
||||||
|
QCOMPARE(negativeZeroIdentity.scalar(), qreal(1.0));
|
||||||
|
QVERIFY(negativeZeroIdentity.isIdentity());
|
||||||
|
|
||||||
QQuaternion v1(34.0f, 1.0f, 2.5f, -89.25f);
|
QQuaternion v1(34.0f, 1.0f, 2.5f, -89.25f);
|
||||||
QCOMPARE(v1.x(), (qreal)1.0f);
|
QCOMPARE(v1.x(), (qreal)1.0f);
|
||||||
QCOMPARE(v1.y(), (qreal)2.5f);
|
QCOMPARE(v1.y(), (qreal)2.5f);
|
||||||
|
@ -162,6 +162,11 @@ void tst_QVectorND::create2()
|
|||||||
QCOMPARE(null.y(), (qreal)0.0f);
|
QCOMPARE(null.y(), (qreal)0.0f);
|
||||||
QVERIFY(null.isNull());
|
QVERIFY(null.isNull());
|
||||||
|
|
||||||
|
QVector2D nullNegativeZero(qreal(-0.0), qreal(-0.0));
|
||||||
|
QCOMPARE(nullNegativeZero.x(), (qreal)-0.0f);
|
||||||
|
QCOMPARE(nullNegativeZero.y(), (qreal)-0.0f);
|
||||||
|
QVERIFY(nullNegativeZero.isNull());
|
||||||
|
|
||||||
QVector2D v1(1.0f, 2.5f);
|
QVector2D v1(1.0f, 2.5f);
|
||||||
QCOMPARE(v1.x(), (qreal)1.0f);
|
QCOMPARE(v1.x(), (qreal)1.0f);
|
||||||
QCOMPARE(v1.y(), (qreal)2.5f);
|
QCOMPARE(v1.y(), (qreal)2.5f);
|
||||||
@ -252,6 +257,12 @@ void tst_QVectorND::create3()
|
|||||||
QCOMPARE(null.z(), (qreal)0.0f);
|
QCOMPARE(null.z(), (qreal)0.0f);
|
||||||
QVERIFY(null.isNull());
|
QVERIFY(null.isNull());
|
||||||
|
|
||||||
|
QVector3D nullNegativeZero(qreal(-0.0), qreal(-0.0), qreal(-0.0));
|
||||||
|
QCOMPARE(nullNegativeZero.x(), (qreal)-0.0f);
|
||||||
|
QCOMPARE(nullNegativeZero.y(), (qreal)-0.0f);
|
||||||
|
QCOMPARE(nullNegativeZero.z(), (qreal)-0.0f);
|
||||||
|
QVERIFY(nullNegativeZero.isNull());
|
||||||
|
|
||||||
QVector3D v1(1.0f, 2.5f, -89.25f);
|
QVector3D v1(1.0f, 2.5f, -89.25f);
|
||||||
QCOMPARE(v1.x(), (qreal)1.0f);
|
QCOMPARE(v1.x(), (qreal)1.0f);
|
||||||
QCOMPARE(v1.y(), (qreal)2.5f);
|
QCOMPARE(v1.y(), (qreal)2.5f);
|
||||||
@ -379,6 +390,13 @@ void tst_QVectorND::create4()
|
|||||||
QCOMPARE(null.w(), (qreal)0.0f);
|
QCOMPARE(null.w(), (qreal)0.0f);
|
||||||
QVERIFY(null.isNull());
|
QVERIFY(null.isNull());
|
||||||
|
|
||||||
|
QVector4D nullNegativeZero(qreal(-0.0), qreal(-0.0), qreal(-0.0), qreal(-0.0));
|
||||||
|
QCOMPARE(nullNegativeZero.x(), (qreal)-0.0f);
|
||||||
|
QCOMPARE(nullNegativeZero.y(), (qreal)-0.0f);
|
||||||
|
QCOMPARE(nullNegativeZero.z(), (qreal)-0.0f);
|
||||||
|
QCOMPARE(nullNegativeZero.w(), (qreal)-0.0f);
|
||||||
|
QVERIFY(nullNegativeZero.isNull());
|
||||||
|
|
||||||
QVector4D v1(1.0f, 2.5f, -89.25f, 34.0f);
|
QVector4D v1(1.0f, 2.5f, -89.25f, 34.0f);
|
||||||
QCOMPARE(v1.x(), (qreal)1.0f);
|
QCOMPARE(v1.x(), (qreal)1.0f);
|
||||||
QCOMPARE(v1.y(), (qreal)2.5f);
|
QCOMPARE(v1.y(), (qreal)2.5f);
|
||||||
|
Loading…
Reference in New Issue
Block a user