C++ 如何比较限制小数位数的双精度值?

C++ 如何比较限制小数位数的双精度值?,c++,qt,C++,Qt,Qt提供了qFuzzyCompare功能来比较双倍,例如: bool compare(double value1, double value2) { return qFuzzyCompare(value1, value2); } 如果我尝试比较以下值387.109287103和387.109287101,qFuzzyCompare将返回false,这是有意义的,因为这些值不相等 如何限制小数位数以比较两个双精度值? 例如,将小数位限制为6,两个值(387.109287和387.1092

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

bool compare(double value1, double value2)
{
    return qFuzzyCompare(value1, value2);
}
如果我尝试比较以下值
387.109287103
387.109287101
qFuzzyCompare
将返回
false
,这是有意义的,因为这些值不相等

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

例如,将小数位限制为
6
,两个值(
387.109287
387.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;
}
#包括
#包括
布尔比较(双值1,双值2)
{
返回qFuzzyCompare(值1、值2);
}
布尔比较(双值1、双值2、五次精度)
{
value1=QString::number(value1,'f',精度).toDouble();
value2=QString::number(value2,'f',精度).toDouble();
返回qFuzzyCompare(值1、值2);
}
int main()
{

qDebug()比较两个浮点值的常用方法是将它们彼此相减,得到结果的绝对值,然后将其与ε值进行比较

在你的情况下,可能是这样的

bool compare(double value1, double value2, quint8 precision)
{
    return std::abs(value1 - value2) < std::pow(10, -precision);
}
bool比较(双值1、双值2、精度8)
{
返回标准::绝对值(值1-值2)<标准::功率(10-精度);
}

对于精度如
6
,则
std::pow(10,-精度)
应等于
0.000001
(这是ε),如果两个值之间的差值小于它们被视为相等的值。

接受的答案将返回真值(相等),例如:5.12和5.11,而不是小数点后两位:

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.00999999999787

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

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;
}
bool比较(常数双精度值1、常数双精度值2、常数整数精度)
{
int64_t震级=静态施法(标准::功率(10,精度));
int64_t intValue1=静态投射(值1*幅度);
int64_t intValue2=静态投射(值2*幅度);
返回intValue1==intValue2;
}

10^precision
乘法的可能重复,转换为int然后比较?@cse我不认为它是重复的。另一个问题与限制小数位数无关。@KelvinS在提供的答案中提到:内部
Qt
使用`(qAbs(p1-p2)*10000000000@rafix07通常的算术转换会导致整数提升,因此结果将是一个
int
。这将返回true(等于),例如:5.12和5.11,而不是小数点后两位。有关详细信息,请参阅下面的答案。