C++的float类型数比较问题

2020.8.17更新了一下,看到了两个float数比较的,不是0值,也加进了最末尾。

相等比较

之前刷题做到一道题,看到题解很奇怪:
计算一个数字的立方根,getCubeRoot(double input)。
题解采用了二分法,但比较时并不是用直接==比较是不是达到了目标值,而是这样写的:

if(mid*mid*mid-a<0.0000001 && mid*mid*mid-a>-0.00000001)
printf("%.1lf",mid);

当时就有点懵,今天又看到了一道面试题:

写出float x 与“零值”比较的if语句

看了题解:

const float EPSINON = 0.00001; 
if ((x >= - EPSINON) && (x <= EPSINON) 

竟然又是这种形式,遂去查了相关资料,才弄明白为什么要这样写。

不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。

EPSINON应该是一个很小的值吧 因为计算机在处理浮点数的时候是有误差的,所以判断两个浮点数是不是相同,是要判断是不是落在同一个区间的,这个区间就是 [-EPSINON,EPSINON] EPSINON一般很小,10的-6次方以下吧,具体的好像不确定的,和机器有关。

为什么浮点数不能直接作“等值比较”?

因为浮点数表示范围大,如果一个数已经很小的时候,就可以认为是0了,epsinon嘛,limit,极限什么的。也可以想一下,0.9无限循环不是等于1吗?

千万要留意,无论是float还是double类型的变量,都有精度限制。所以一定要避免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。

PS:一个证明的测试例子:
#include <stdio.h>
#include <stdlib.h>

main()
{
float d1, d2, d3, d4;

d1 = 194268.02;
d2 = 194268;
d4 = 0.02;

d3 = d1 - d2;
if (d3 > d4)
   printf(">0.02/n");
else if (d3 < d4)
   printf("<0.02/n");
else
   printf("=0.02/n");    

printf("%f - %f = %f /n", d1,d2,d3);

system("pause");}

请看结果:
<0.02
194268.015625 - 194268.000000 = 0.015625

即:194268.02 - 194268.0 不等于 0.02!
存进去的数居然会变!怕了吧?

4个变量改成double型的,再测试:
这是结果
<0.02
194268.020000 - 194268.000000 = 0.020000
明明是0.02啊,怎么还是小于?
这次没有改我存的数了吧?WHY?

我说,我怕了,以后我再不敢用浮点数直接作相等比较了!

还是那句话:浮点数都是有精度限制的。
所以你存的数,不一定就是你要的数。

大小比较

#define EPSILON 0.000001 //根据精度需要
if ( fabs( fa - fb) < EPSILON )//两个float
{
printf("fa<fb\n");
}

fabs函数
用法:#include <math.h>
功能:求浮点数x的绝对值
说明:计算|x|, 当x不为负时返回x,否则返回-x

abs函数是针对整数的

参考文献:
https://blog.csdn.net/azhang00000/article/details/5357134
https://blog.csdn.net/jk110333/article/details/8902707

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值