我有一个简单的小代码来比较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
答案 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