关闭

浮点数不可以直接用“==”和“!=”进行比较

1123人阅读 评论(0) 收藏 举报

林锐博士在《高质量C++编程指南》中说过:“不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式”,因为那是“隐含错误的写法”。应该设法转化成下面这样的写法:

-------------------------------

const float EPSINON = 0.00001;            //精度限制

if((x >= -EPSINON) && (x <= EPSINON))    //表示x为“零值”

-------------------------------

刚看到的时候没太在意,因为感觉平时编程极少会遇到要比较两个浮点值是否相等的情况。后来得空一想,又想不明白这样写为什么是错的。正巧Wayne过来串门,问他一下,结果他也不太清楚。那好吧,不知道原因,那就先写个程序试一下吧,看到底是不是错误写法:

-------------------------------

#include <iostream>

using std::cout;

using std::endl;


int main()

{

  double ff = 3;

  double aa = 3.6;

  double tmp = aa / 1.2 - ff;

  if (tmp != 0)

  {

    cout << "1" << endl;

  }

  else

  {

    cout << "2" << endl;

  }

  return 0;

}

-------------------------------

在我们看来,上面程序的输出结果应该是2的,但是很遗憾,结果是1。——我在Cygwin中用g++(gcc版本为3.4.4)测试时就是这个结果,但是用VC6.0测试时就是输出2了。可见这种写法不能保证一定正确,果然是隐含错误啊。再来试试林锐博士的办法:

-------------------------------

#include <iostream>

using std::cout;

using std::endl;


int main()

{

  double ff = 3;

  double aa = 3.6;

  double tmp = aa / 1.2 - ff;

  if (tmp < 1e-9999999999999999 && tmp > -1e-9999999999999999)

  {

    cout << "1" << endl;

  }

  else

  {

    cout << "2" << endl;

  }

  return 0;

}

-------------------------------

这下正确了。但是精度最多可以到多少呢?根据我的测试,在上面的if语句中不论写多少个“9”都不会有问题,只要不超出编译器所约束的一行中最大字符数限制就可以了。我用Cygwin中的g++(gcc版本为3.4.4)测试的时候最多写了307209也没有问题,不知道后面到底还可以加多少;但把这个源文件用VC6.0打开时就不行了,提示说“这个文件包含最大2048个字符的长行。行将换行。”,编译自然也是通不过的了。

现在再想想就明白前一种写法为什么不对了,在计算机组成原理中我们学过计算机对浮点数的记录和处理方法。在一系列地计算过程当中,总是少不了“对阶”的操作,这就引入了计算精度的问题。所以就有很多我们人类看着是相等的东西,给计算机看就不等了。

Sumless 2006-6-12

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:71328次
    • 积分:999
    • 等级:
    • 排名:千里之外
    • 原创:21篇
    • 转载:16篇
    • 译文:0篇
    • 评论:45条
    文章分类
    最新评论