浮点数与0比较

前言

在平时的编写代码的过程中,细心的小伙伴们不难发现浮点数的精度的都有些不准确,如下图:
在这里插入图片描述
该篇文章将讲解如应对这种问题。

一、浮点数与0的比较

浮点数在内存中存储,并不想我们想的,是完整存储的,在十进制转化成为二进制,是有可能有精度损失的。
注意这里的损失,不是一味的减少了,还有可能增多。浮点数本身存储的时候,在计算不尽的时候,会“四舍五入

#include<stdio.h>
#include <stdio.h>
#include <windows.h>
int main()
{
	double x = 1.0;
	double y = 0.1;
	printf("%.50f\n", x - 0.9);
	printf("%.50f\n", y);
	if ((x - 0.9) == y) {
		printf("you can see me!\n");
	}
	else {
		printf("oops\n");
	}
	system("pause");
	return 0;
}

在这里插入图片描述
正常应该打印“”you can see me!“”,但实际两数并不相等,因为浮点数精度有缺失。
结论:因为精度损失问题,两个浮点数,绝对不能使用==进行相等比较.
那么两个浮点数该如何比较呢?
应该进行范围精度比较

//伪代码
if((x-y) > -精度 && (x-y) < 精度){
//TODO
}
//伪代码-简洁版
if(fabs(x-y) < 精度){ //fabs是浮点数求绝对值
//TODO
}
精度:
自己设置?后面如果有需要,可以试试,通常是宏定义。
使用系统精度?暂时推荐
#include<float.h> //使用下面两个精度,需要包含该头文件
DBL_EPSILON //double 最小精度
FLT_EPSILON //float 最小精度
//代码调整后
#include <stdio.h>
#include <math.h> //必须包含math.h,要不然无法使用fabs
#include <float.h> //必须包含,要不然无法使用系统精度
#include <windows.h>
int main()
{
double x = 1.0;
double y = 0.1;
printf("%.50f\n", x - 0.9);
printf("%.50f\n", y);
if (fabs((x - 0.9) - y) < DBL_EPSILON){ //原始数据是浮点数,我们就用DBL_EPSILON
printf("you can see me!\n");
}
else{
printf("oops\n");
}
system("pause");
return 0;
}
//两个精度定义
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0
*/
#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0
*/
XXX_EPSILON是最小误差,是:XXX_EPSILON+n不等于n的最小的正数。
EPSILON这个单词翻译过来是'ε'的意思,数学上,就是极小的正数 ----来自百度 :)

所以最后改正结果如下:

#include <stdio.h>
#include <math.h>
#include <float.h>
#include <windows.h>
int main()
{
double x = 0.00000000000000000000001;
//if (fabs(x-0.0) < DBL_EPSILON){ //写法1
//if (fabs(x) < DBL_EPSILON){ //写法2
if(x > -DBL_EPSILON && x < DBL_EPSILON){ //书中写法
printf("you can see me!\n");
}
else{
printf("oops\n");
}
system("pause");
return 0;
}

注:DBL_EPSILON是最小误差。

总结

感谢大家阅读本文章!。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1无名之辈1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值