gcc没有正确比较双重类型变量?

时间:2013-01-15 08:24:04

标签: gcc floating-point double

我甚至不确定我是在问一个问题,这次我发现了一种“四处走动”的方式,但是...我花了几天时间才意识到这就是问题所在......以及其他时间我可能无法绕过它...还有其他人来这个吗?当比较实际上相等的双重类型变量时,结果是“>”...

 printf("compare: %ld ?? %ld\n", (double)( radii(nowX,nowY)*irange2 ),(double)(Rad2*irange2)); getchar();
 if( (double)(radii(nowX,nowY)*irange2)<(double)(Rad2*irange2) ) printf("*** < ***\n"); 
 if( (double)(radii(nowX,nowY)*irange2)>(double)(Rad2*irange2) ) printf("*** > ***\n");
 if( (double)(radii(nowX,nowY)*irange2)==(double)(Rad2*irange2) ) printf("*** == ***\n")
 printf("SECOND = %d\n", ((double)(radii(nowX,nowY)*irange2))<= ( (double)(Rad2*irange2)

输出:

compare: 1509949.440000 ?? 1509949.440000
*** > ***
SECOND = 0

 printf("compare: %ld ?? %ld\n", (long)( radii(nowX,nowY)*irange2 ), (long)(Rad2*irange2)); getchar();
 if( (long)(radii(nowX,nowY)*irange2)<(long)(Rad2*irange2) ) printf("*** < ***\n");
 if( (long)(radii(nowX,nowY)*irange2)>(long)(Rad2*irange2) ) printf("*** > ***\n"); 
 if( (long)(radii(nowX,nowY)*irange2)==(long)(Rad2*irange2) ) printf("*** == ***\n")
 printf("SECOND = %d\n",  ((long)(radii(nowX,nowY)*irange2))<= ( (long)(Rad2*irange2) ) ); getchar();

输出:

compare: 1509949 ?? 1509949

*** == ***
SECOND = 1

2 个答案:

答案 0 :(得分:2)

这里的问题是浮点运算用于进行近似算术,因此它会得到各种错误的结果,而且你没有显示数字的完整值。

完全显示后,数字看起来不相等。

比较平等并不是这里的罪恶行动。如果输入错误,几乎所有功能都无法给出正确的结果。例如,如果计算一个值为零或正值的平方根(如果精确计算但由于先前的舍入误差而略微为负),则会得到一个例外,用于取负数的平方根。

当舍入近似结果,减去近似结果(因增加相对误差的大小而臭名昭着)和其他函数时,会发生类似的问题。 具有浮点的所有操作,不仅要比较相等,还应考虑结果是近似的事实(除非经过精心设计)。

答案 1 :(得分:1)

这种情况正在发生,因为根据计算,双值可能会略有不同。因此,不建议检查是否相等。相反,检查两个双打是否非常彼此接近。另请参阅this link以获取解释。

编辑:只是为了清除这一点:对于所有浮点类型都是如此,因为这是它们存储方式所固有的。