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 <thiago.macieira@intel.com> (cherry picked from commit 1fe60cbcc3c476f5f4bc4bce49d4e73d99c49d3d) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
4ba4723d57
commit
f00f557ee6
@ -173,20 +173,20 @@ static std::optional<qlonglong> qConvertToNumber(const QVariant::Private *d, boo
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static std::optional<qreal> qConvertToRealNumber(const QVariant::Private *d)
|
||||
static std::optional<double> qConvertToRealNumber(const QVariant::Private *d)
|
||||
{
|
||||
bool ok;
|
||||
switch (d->typeInterface()->typeId) {
|
||||
case QMetaType::QString:
|
||||
if (double r = d->get<QString>().toDouble(&ok); ok)
|
||||
return qreal(r);
|
||||
return r;
|
||||
return std::nullopt;
|
||||
case QMetaType::Double:
|
||||
return qreal(d->get<double>());
|
||||
return d->get<double>();
|
||||
case QMetaType::Float:
|
||||
return qreal(d->get<float>());
|
||||
return double(d->get<float>());
|
||||
case QMetaType::Float16:
|
||||
return qreal(d->get<qfloat16>());
|
||||
return double(d->get<qfloat16>());
|
||||
case QMetaType::ULongLong:
|
||||
case QMetaType::UInt:
|
||||
case QMetaType::UChar:
|
||||
@ -194,7 +194,7 @@ static std::optional<qreal> 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<QCborValue>().toDouble();
|
||||
@ -204,7 +204,7 @@ static std::optional<qreal> qConvertToRealNumber(const QVariant::Private *d)
|
||||
default:
|
||||
// includes enum conversion as well as invalid types
|
||||
if (std::optional<qlonglong> 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<qreal> r1 = qConvertToRealNumber(d1);
|
||||
std::optional<qreal> 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<qreal>(*r1, *r2);
|
||||
return spaceShip(*r1, *r2);
|
||||
}
|
||||
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
|
Loading…
x
Reference in New Issue
Block a user