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

原创 2006年06月12日 01:13:00

林锐博士在《高质量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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

为什么两个不确定值的浮点数无法直接比较是否相等

C语言贴吧看到的: 首先,为了让代码清楚一点,把楼主耍小聪明的伎俩去掉: 程序运行的结果是执行了if (a != a) 语句块的内容。 a = a / a 没什么好奇怪的,关于执行的结果我开...

浮点数的比较问题,不能直接比较,需用精度

浮点数比较问题1、直接进行关系比较的错误(==)浮点数可以进行比较,但是由于不同浮点类型中表示精度的差异,所以会引起一些错误。例1:#include void main(){       floatf...

浮点数的比较问题,不能直接比较,需用精度

浮点数比较问题1、直接进行关系比较的错误(==)浮点数可以进行比较,但是由于不同浮点类型中表示精度的差异,所以会引起一些错误。例1:#include void main(){       floatf...

浮点数的比较问题,不能直接比较,需用精度

浮点数比较问题1、直接进行关系比较的错误(==)浮点数可以进行比较,但是由于不同浮点类型中表示精度的差异,所以会引起一些错误。例1:#include void main(){       floatf...

浮点数的比较问题,不能直接比较,需用精度

浮点数比较问题1、直接进行关系比较的错误(==)浮点数可以进行比较,但是由于不同浮点类型中表示精度的差异,所以会引起一些错误。例1:#include void main(){       floatf...

浮点数的比较问题,不能直接比较,需用精度

浮点数比较问题1、直接进行关系比较的错误(==)浮点数可以进行比较,但是由于不同浮点类型中表示精度的差异,所以会引起一些错误。例1:#include void main(){       floatf...

浮点数的比较问题,不能直接比较,需用精度

浮点数比较问题1、直接进行关系比较的错误(==)浮点数可以进行比较,但是由于不同浮点类型中表示精度的差异,所以会引起一些错误。例1:#include void main(){       floatf...

frame animation不可以直接写在oncreate方法中

Frame Animation是顺序播放事先做好的图像,跟电影类似。不同于animation package, Android SDK提供了另外一个类AnimationDrawable来定义、使用Fr...

Java和C#中String直接赋值与使用new创建(==与equals进行比较)的区别

在Java中,字符串可以直接赋值或者使用new来新建,直接赋值的话是编译阶段(.class文件)中就将该字符串值放到常量池中,以后如果有其他变量直接赋予同样的值的话就不再分配内存空间,而是直接给它个引...
  • iqv520
  • iqv520
  • 2013-08-25 11:25
  • 3716
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)