两个双精度值的 C++ 比较无法正常工作

c++ comparison of two double values not working properly

本文关键字:常工作 工作 比较 两个 双精度 C++      更新时间:2023-10-16

看看这段代码:

#include <cmath>
#include <iostream>
using namespace std;
class Sphere
{
    double r;
public:
    double V() const { return (4/3) * 3.14 * pow(r,3); }
    bool equal(const Sphere& s) const
    {
        cout  << V() << " == " << s.V() << " : " << ( V() == s.V() );
        return ( V() == s.V() );
    }
    explicit Sphere(double rr = 1): r(rr){}
};
main()
{
    Sphere s(3);
    s.equal(s);
}

输出是84.78 == 84.78 : 0这意味着相同的方法不会每次都返回相同的值,即使所有参数都是静态的?

但是,如果我在V()方法定义中编写3.0而不是3.14,如下所示:

double V() const { return (4/3) * 3.0 * pow(r,3); }

然后,输出为:84.78 == 84.78 : 1

这是怎么回事?我的程序需要这种方法,它将比较两个对象的体积,但这是不可能的?我砰�它是否与编译器(GCC)有关,或者我在这里错过了一些重要的东西?

使用 == 运算符比较浮点值非常容易出错;两个应该相等的值可能不是由于算术舍入误差。比较这些的常用方法是使用 epsilon:

bool double_equals(double a, double b, double epsilon = 0.001)
{
    return std::abs(a - b) < epsilon;
}

浮点比较有两个问题:

(1) 浮点运算通常至少涉及难以预测的微小舍入误差。因此,两个应该在数学上给出相同结果的浮点运算(如 4.7 * (1.0/3.14) 与 4.7/3.14)可能会给出不同的结果。

(2) 允许编译器执行浮点运算,有时精度高于必要的精度。它还允许以其他时间所需的精度执行完全相同的浮点运算。因此,完全相同的操作可能会产生略有不同的结果,这就是您在此处看到的。

为了解决OP的问题,这看起来像是由(2)引起的。我会尝试找出是否有任何编译器选项可以阻止编译器使用比所需更高的精度。