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