Qt provides the qFuzzyCompare
function to compare doubles , for example:
bool compare(double value1, double value2)
{
return qFuzzyCompare(value1, value2);
}
If I try to compare the following values 387.109287103
and 387.109287101
, qFuzzyCompare
will return false
, what makes sense, since the values are not equal.
How can I limit the decimal places to compare two double values?
For example, limiting the decimal places to 6
the two values ( 387.109287
and 387.109287
) will be equal.
I have implemented the following function to do that:
bool compare(double value1, double value2, quint8 precision)
{
value1 = QString::number(value1, 'f', precision).toDouble();
value2 = QString::number(value2, 'f', precision).toDouble();
return qFuzzyCompare(value1, value2);
}
But I'm not sure if it is the best way to do that, since it convert the values to QString
and then convert back to double
.
Here is the full example:
#include <QDebug>
#include <QtGlobal>
bool compare(double value1, double value2)
{
return qFuzzyCompare(value1, value2);
}
bool compare(double value1, double value2, quint8 precision)
{
value1 = QString::number(value1, 'f', precision).toDouble();
value2 = QString::number(value2, 'f', precision).toDouble();
return qFuzzyCompare(value1, value2);
}
int main()
{
qDebug() << compare(387.109287103, 387.109287101); // False
qDebug() << compare(387.109287103, 387.109287101, 6); // True
return 0;
}
Note : I'm using Qt 5.3.
The usual way to compare two floating point values is to subtract them from each other, get the absolute value of the result, and compare it to an epsilon value.
In your case it could be something like
bool compare(double value1, double value2, quint8 precision)
{
return std::abs(value1 - value2) < std::pow(10, -precision);
}
For a precision of eg 6
then std::pow(10, -precision)
should equal 0.000001
(this is the epsilon ), and if the difference between the two values is smaller than that they are considered equal.
The accepted answer will return true (is equal) for eg: 5.12 and 5.11 compared to 2 decimal places:
double value1 = 5.12;
double value2 = 5.11;
bool result = compare2(value1, value2, 2); // result will be true
This is because 5.12 - 5.11 equals to 0.01 but will be represented as 0.009999999999999787 in the floating point number.
I am using the following approach instead that works around this problem by doing an integer comparison:
bool compare(const double value1, const double value2, const int precision)
{
int64_t magnitude = static_cast<int64_t>(std::pow(10, precision));
int64_t intValue1 = static_cast<int64_t>(value1 * magnitude);
int64_t intValue2 = static_cast<int64_t>(value2 * magnitude);
return intValue1 == intValue2;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.