如何比较限制小数位的双值?

时间:2017-12-20 12:34:46

标签: c++ qt

Qt 提供qFuzzyCompare功能来比较双打,例如:

bool compare(double value1, double value2)
{
    return qFuzzyCompare(value1, value2);
}

如果我尝试比较以下值387.109287103387.109287101qFuzzyCompare将返回false,这是有道理的,因为值不相等。

如何限制小数位以比较两个双倍值?

例如,将小数位数限制为6两个值(387.109287387.109287)将相等。

我已经实现了以下功能:

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);
}

但我不确定这是否是最好的方法,因为它将值转换为QString,然后转换回double

以下是完整示例:

#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;
}

注意:我使用的是Qt 5.3。

2 个答案:

答案 0 :(得分:9)

比较两个浮点值的常用方法是将它们相互减去,得到结果的绝对值,并将其与 epsilon 值进行比较。

在你的情况下,它可能类似于

bool compare(double value1, double value2, quint8 precision)
{
    return std::abs(value1 - value2) < std::pow(10, -precision);
}

对于例如精度6然后std::pow(10, -precision)应该等于0.000001(这是 epsilon ),如果两个值之间的差异小于它们,则认为它们相等。< / p>

答案 1 :(得分:0)

接受的答案将返回true(等于),例如:5.12和5.11,而小数点后2位:

double value1 = 5.12;
double value2 = 5.11;
bool result = compare2(value1, value2, 2); // result will be true

这是因为5.12-5.11等于0.01,但是在浮点数中将表示为0.009999999999999787。

我正在使用以下方法,通过进行整数比较来解决此问题:

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;
}