float变量与“零值”的比较

目录

1.问题的引出:

2.解决方案

<1>:自定义精度

<2>:系统提供的精度

3.总结 


1.问题的引出:

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

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

#include<stdio.h>
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 ,那么输出结果为是否为这样呢?

代码运行后的结果为:

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


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

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

代码运行后的结果为:

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

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


2.解决方案

<1>:自定义精度

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

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

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

#include<stdio.h>
#include<math.h>
#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;
}

 程序运行的结果为:

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

<2>:系统提供的精度

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

                               --- FLT_EPSILON

 

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

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

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

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

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;
}

​

运行结果为:

我们可以看出,此时的输出结果为 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的概念。

不可以添加等号(=)。


 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值