C++ 如何比较限制小数位数的双精度值?
Qt提供了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
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,而不是小数点后两位。有关详细信息,请参阅下面的答案。