c ++两个double值的比较不能正常工作

tuk*_*uks 15 c++ double comparison

看看这段代码:

#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);
}
Run Code Online (Sandbox Code Playgroud)

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

但是如果我写的3.0不是3.14V()方法定义中,就像这样:

double V() const { return (4/3) * 3.0 * pow(r,3); }
Run Code Online (Sandbox Code Playgroud)

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

这里发生了什么?我需要这个方法,对于我的程序,它将比较两个对象的体积,但这是不可能的?我把头撞了很长时间才弄明白问题的原因是什么,幸运的是我找到了它,但现在我不明白为什么?它与编译器(GCC)有关,还是我错过了重要的东西?

nij*_*sen 26

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

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

  • @PeteBecker浮点算术不是微不足道的,没有"初学者的方式"这样做. (3认同)
  • 不能。“几乎等于”是一种先进的技术。初学者不应该使用它。一个严重的问题是,“ a几乎等于b”和“ b几乎等于c”并不意味着“ a几乎等于c”。 (2认同)
  • 我不希望 double_equals (1e-6, -1e-5) 返回“true”。 (2认同)