float变量与“零值”的比较

目录

1.问题的引出:

2.解决方案

<1>:自定义精度

<2>:系统提供的精度

3.总结 


1.问题的引出:

浮点数在存储的时候,会存在精度的损失

那么在浮点数进行比较的时候,可不可以使用 == 来进行比较,测试代码如下:

#include
int main()
{
	double a = 1.0;
	double b = 0.1;
	if ((a - 0.9) == 0.1)
	{
		printf("hahaha\n");
	}
	else
	{
		printf("hehehe\n");
	}
	return 0;
}

 在我们的认知里,a - 0.9 = 1.0-0.9 = 0.1 即程序运行成功后会输出 hahaha ,那么输出结果为是否为这样呢?

代码运行后的结果为:

float变量与“零值”的比较_第1张图片

得出结论:浮点数在进行比较的时候,绝对不可以直接使用 == 来进行比较


 为什么会产生上述结果呢?在此处我们将 a - 0.9 的值打印出来,同时为了更好更好地进行后续代码分析,我们将 0.1 的值也打印出来,代码为:

#include
int main()
{
	double a = 1.0;
	double b = 0.1;
	printf("%.50lf\n", a - 0.9);
	printf("%.50lf\n", b);
	//保留小数点后50位
	return 0;
}

代码运行后的结果为:

float变量与“零值”的比较_第2张图片

 在此处我们发现,与我们想象中的并不相同,a - 0.9 != 0.1,佐证了上述比较代码的真实性。

原因是,浮点数在存储的过程中存在精度损失,会导致结果存在细微的差别。


2.解决方案

<1>:自定义精度

在此处需要介绍一个函数 --- fabs (求绝对值函数)

float变量与“零值”的比较_第3张图片

 我们可以自行定义一个精度,只要两浮点数相减的绝对值在我们定义的精度之内,我们就可以判定这两个浮点数相等。

对进行比较的代码稍作修改:

#include
#include
#define EPS 0.00000000000001
int main()
{
	double a = 1.0;
	double b = 0.1;
	if (fabs((a - 0.9)-0.1) < EPS)
	{
		printf("hahaha\n");
	}
	else
	{
		printf("hehehe\n");
	}
	return 0;
}

 程序运行的结果为:

float变量与“零值”的比较_第4张图片

 我们可以看出,此时的输出结果为 hahaha ,不在为 hehehe 。

<2>:系统提供的精度

 系统提供的精度为 --- DBL_EPSILON , 我们将其转到定义可以看到:

                               --- FLT_EPSILON

 

 XXX_EPSILON 是最小误差 --- 即:XXX_EPSILON + n 不等于 n 的最小正数

有很多数字 + n 都可以不等于 n 但是  XXX_EPSILON 是最小的。

对比较的代码进行变化,得出下列代码:

#include
#include
#include

int main()
{
	double a = 1.0;
	double b = 0.1;
	if (fabs((a - 0.9) - 0.1) < FLT_EPSILON)
	{
		printf("hahaha\n");
	}
	else
	{
		printf("hehehe\n");
	}
	return 0;
}

​

运行结果为:

float变量与“零值”的比较_第5张图片

我们可以看出,此时的输出结果为 hahaha ,不在为 hehehe 。

3.总结 


 float 变量与 0 比较,只需要比较是否在精度范围内。

if (fabs((a - 0.9) - 0.1) < DBL_EPSILON) 可近似看作 if(fabs(x) <  DBL_EPSILON)

思考,在此处是否可以改为 <= ???

fabs(x)=DBL_EPSILON;

即 double y + x != y; // x  为精度 --- 引起数据变化的最小值。

参考: 0 的定义 ---  y + 0.0 = y;

我们可以得出,fabs(x) <=  DBL_EPSILON(确认是否为0的逻辑),如果 = , 就说明 x 本身已经能够引起其他和它+-的数据本身的变化了,不符合0的概念。

不可以添加等号(=)。


float变量与“零值”的比较_第6张图片

 

你可能感兴趣的:(c语言)