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 Pick-to: 6.6 6.5 6.2 Change-Id: I198ec2c39913b501ef2fe99ae3048b160baa1fd8 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
5f9ab113e3
commit
1fe60cbcc3
@ -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