3.2 float 变量与"零值"进行比较
浮点数在内存中存储,并不想我们想的,是完整存储的,在十进制转化成为二进制,是有可能有精度损失的。
注意这里的损失,不是一味的减少了,还有可能增多。浮点数本身存储的时候,在计算不尽的时候,会 “ 四舍五入 ”或者其他策略
结论:因为精度损失问题,两个浮点数,绝对不能使用==进行相等比较.
那么两个浮点数该如何比较呢?
应该进行范围精度比较:
#include<float.h> //使用下面两个精度,需要包含该头文件 DBL_EPSILON //double 最小精度 FLT_EPSILON //float 最小精度
//伪代码 if((x-y) > -精度 && (x-y) < 精度){ //TODO } //伪代码-简洁版 if(fabs(x-y) < 精度){ //fabs是浮点数求绝对值 //TODO }
精度:
自己设置?后面如果有需要,可以试试,通常是宏定义。
使用系统精度?暂时推荐
//代码调整后 #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 这个单词翻译过来是 'ε' 的意思,数学上,就是极小的正数
所以我们再回来讲float和0的比较:
#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; }
有朋友就有疑问了?
//x > -DBL_EPSILON && x < DBL_EPSILON: 为何不是 >= && <= 呢?
// 个人看法: XXX_EPSILON 是最小误差 , 是: XXX_EPSILON+n 不等于 n 的最小的正数。
//XXX_EPSILON+n 不等于 n 的最小的正数 : 有很多数字 +n 都可以不等于 n ,但是 XXX_EPSILON 是最小的, but ,
XXX_EPSILON 依旧是引起不等的一员。
// 换句话说: fabs(x) <= DBL_EPSILON( 确认 x 是否是 0 的逻辑 ) ,如果 = ,就说明 x 本身,已经能够引起其他和他 +- 的数
据本身的变化了,这个不符合 0 的概念。
3.3 指针变量与“零值”进行比较
其实NULL 和 '/0' 和 0 都是0。只不过因为编译器编译的时候需要相同的类型进行计算,所以就有了“各种不同的0”。
else 到底与哪个 if 配对呢?
其实并不是看着这样的理解,推荐的写法是:
总结:else 匹配采取就近原则
今天的内容就到这里了哈!!!
要是认为作者有一点帮助你的话!
就来一个点赞加关注吧!!!当然订阅是更是求之不得!
最后的最后谢谢大家的观看!!!
你们的支持是作者写作的最大动力!!!
下期见哈!!!