C:为什么晶圆厂在比较浮点数时会给出奇怪的结果?

时间:2013-05-31 12:51:56

标签: c floating-point

我有一个简单的小代码来比较2个浮点数:

我尝试使用晶圆厂,但它给出了错误的奇怪结果。什么是错误,什么是正确的形式?

#include <stdio.h>
#include <stdlib.h>
#include <float.h>

void compareFloat(double a1, double a2)
{
   if(fabs(a1 - a2) < DBL_EPSILON)
       printf("a1 is smaller\n");
   else
       printf("a1 is larger\n");
}

int main()
{
 float a1=0.0000004f, a2=0.0005f;
 compareFloat(a1, a2);
}

此代码中的错误是什么?它总是打印a1 is smaller即使我设置a1 = 0.004f和a2 = 0.0005f

3 个答案:

答案 0 :(得分:4)

abs的原型是一个整数!

int abs (int number);

你想要fabs浮点

double fabs (double number);

答案 1 :(得分:3)

fabs(a1 - a2) < DBL_EPSILON从浮点数(FP)中取出“浮动”。

FP编号以对数方式分布。即使fabs(a1 - a2) < DBL_EPSILON是相邻的FP值,a1,a2对于大的不同数字也始终为false。对于小FP数,fabs(a1 - a2) < DBL_EPSILON总是如此,即使它们的价值差异很大。

相反,缩放 epsilon

将2个数字比作5个结果

void compareFloat(double a1, double a2) {
  if(a1 == a2) // Typically not performed is applications, but here for illustration.
   printf("a1 is exactly equal to a2\n");
  else if(fabs(a1 - a2) <= (DBL_EPSILON *fabs(a1)) )
   printf("a1 is nearly equal to a2\n");
  else if(a1 < a2)
   printf("a1 is smaller than a2\n");
  else if(a1 > a2)
    printf("a1 is larger than a2\n");
  else 
    printf("a1 is not comparable to a2, at least one of them is a Not-a-Number\n");
}

正如其他人所说,请务必使用fabs()代替abs()

答案 2 :(得分:2)

这在数学上是错误的。你实际上是想比较两个浮点数是否相等,而不是更大/更小。

要比较哪一个较大,只需使用operator<,例如:

if( abs(a1 - a2) > DBL_EPSILON && a1 < a2 )
// ....

假设:a1 == 1.a2 == 5.。然后fabs( a1 - a2 )将大于DBL_EPSILON,但意味着a1 > a2


已经提到了另一个错误 - abs适用于int egers,您需要fabs



编辑:我创建了一个额外的函数来比较浮点数,例如:

bool areEqual( double x, double y )
{
     return ( fabs( x - y ) < DBL_EPSILON );
}

然后直接使用它 - 将使您的代码更具可读性。用法示例:

if( areEqual( a1, a2 ) )
    // equal
else if( a1 < a2 )  // here, it's guaranteed, that a1 != a2, so it's safe now
    // a1 is smaller
else
    // a2 is smaller