From f00f557ee6eea47481d1cc924bb8284432065d86 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 4 Jul 2023 18:47:26 +0200 Subject: [PATCH] QVariant: always compare floating point with double precision When Qt is configured with `-qreal float`, then we should still compare QVariants containing floating point values with the full precision of the stored type, and not cast to qreal (ie. float). Cast all floating point types up to double, which is the highest- precision floating point type we support in Qt. This might have a small performance impact when compiling with `-qreal float`, if the FPU does not perform well with double-precision floating point values. We don't test any `-qreal float` configurations in CI, so not adding a unit test for this. Fixes: QTBUG-114991 Change-Id: I198ec2c39913b501ef2fe99ae3048b160baa1fd8 Reviewed-by: Thiago Macieira (cherry picked from commit 1fe60cbcc3c476f5f4bc4bce49d4e73d99c49d3d) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/kernel/qvariant.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 30da12c95b1..a2767396a89 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -173,20 +173,20 @@ static std::optional qConvertToNumber(const QVariant::Private *d, boo return std::nullopt; } -static std::optional qConvertToRealNumber(const QVariant::Private *d) +static std::optional qConvertToRealNumber(const QVariant::Private *d) { bool ok; switch (d->typeInterface()->typeId) { case QMetaType::QString: if (double r = d->get().toDouble(&ok); ok) - return qreal(r); + return r; return std::nullopt; case QMetaType::Double: - return qreal(d->get()); + return d->get(); case QMetaType::Float: - return qreal(d->get()); + return double(d->get()); case QMetaType::Float16: - return qreal(d->get()); + return double(d->get()); case QMetaType::ULongLong: case QMetaType::UInt: case QMetaType::UChar: @@ -194,7 +194,7 @@ static std::optional qConvertToRealNumber(const QVariant::Private *d) case QMetaType::Char32: case QMetaType::UShort: case QMetaType::ULong: - return qreal(qMetaTypeUNumber(d)); + return double(qMetaTypeUNumber(d)); #ifndef QT_BOOTSTRAPPED case QMetaType::QCborValue: return d->get().toDouble(); @@ -204,7 +204,7 @@ static std::optional qConvertToRealNumber(const QVariant::Private *d) default: // includes enum conversion as well as invalid types if (std::optional l = qConvertToNumber(d)) - return qreal(*l); + return double(*l); return std::nullopt; } } @@ -2372,15 +2372,15 @@ static QPartialOrdering numericCompare(const QVariant::Private *d1, const QVaria if (promotedType != QMetaType::QReal) return integralCompare(promotedType, d1, d2); - // qreal comparisons - std::optional r1 = qConvertToRealNumber(d1); - std::optional r2 = qConvertToRealNumber(d2); + // floating point comparison + const auto r1 = qConvertToRealNumber(d1); + const auto r2 = qConvertToRealNumber(d2); if (!r1 || !r2) return QPartialOrdering::Unordered; if (*r1 == *r2) return QPartialOrdering::Equivalent; - return spaceShip(*r1, *r2); + return spaceShip(*r1, *r2); } #ifndef QT_BOOTSTRAPPED