C/C++ 浮点数比较问题

Posted yhl_leo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++ 浮点数比较问题相关的知识,希望对你有一定的参考价值。


本系列文章由 @YhL_Leo 出品,转载请注明出处。
文章链接: http://blog.csdn.net/yhl_leo/article/details/50255623


Never try to check two floating point variables for equality

C/C++ 浮点数比较是否相等时,有些细节必须要意识到,,例如下面的代码:

#include <iostream>

using namespace std;

void main()

    double epsilon=0.001;
    double d1=2.334;
    double d2=2.335;

    cout << "epsilon is: " << epsilon << endl;
    cout << "d2-d1 is: " << d2-d1 << endl;

    if ((d2 - d1) == epsilon)
        cout << "Equal!" << endl;
    
    else
        cout << "Not equal!" << endl;
    

其输出结果实际上是:

epsilon is: 0.001
d2-d1 is: 0.001
Not equal!

为何会这样呢?让我们稍微调整一下上面的代码:

cout<<"epsilon is: "<< setprecision(20) << epsilon<<endl;
cout<<"d2-d1   is: "<< setprecision(20) << d2-d1 <<endl;

可以得到:

epsilon is: 0.00100000000000000000
d2-d1 is: 0.00099999999999988987

这里引出一条C/C++中非常重要的原则:

The important rule to remember is that powers of two and integer multiples thereof can be perfectly represented. everything else is an approximation.

直译过来意识就是,除了可以表示为2的幂次以及整数数乘的浮点数可以准确表示外,其余的数的值都是近似值。

例如,1.5可以精确表示,因为1.5 = 3*2^(-1);然而3.6却不能精确表示,因为它并不满足这一规则。

此处的例子程序里,这里如果想要判断这样两个浮点数,是否相等,采用==结果就会看似出乎意料,可以调整为:

if(abs(d2 - d1) < epsilon)

以上是关于C/C++ 浮点数比较问题的主要内容,如果未能解决你的问题,请参考以下文章

Lua和C++中的浮点数的比较

Lua和C++中的浮点数的比较

浮点数的比较

C/C++:浮点比较速度

C语言对两个浮点数进行比较的方法

浮点数的精确值作为有理数