• 浮点数变量与0值比较的那些事


    发一下牢骚和主题无关:

        在条件判断的时候,我们经常会碰到与0值比拟的情况,但是通常有很多人使用时采用不恰当的条件判断。上面我们就详细讨论各种情况:

        1. 布尔变量与零值的比拟:

        假设布尔变量的变量名为flag,则它和0值比拟的条件判断语句如下:

        if(flag)

        //表示flag为真

        if(!flag)

        //表示flag为假

        原因:根据布尔类型的语义,0为假,任何非0都为真,也许有人会认为那直接用上面这类写法也行啊,

        if(flag != 0)

        //表示flag为真

        if(flag == 0)

        //表示flag为假

        根据定义,似乎是对的,当然,在程序中也不会错,但是我们会以为这是布尔类型和整型的比拟,类型

        不匹配!当然,还有上面一种方法。

        if(flag == TRUE)

        //表示flag为真

        if(flag == FALSE)

        //表示flag为假

        不错,对于很多语言,都有这两个关键字,而且FALSE被定义为0,但是只要TRUE,大多数语言都将其定义

        为1,而这却没有遵循布尔类型的定义(非零表示真),这样的比拟就会出现bug,比如flag=2时,就不会执行flag为真时的语句。

        综上所述,布尔类型的变量和0值比拟是应采用以下写法:

        if(flag)

        //表示flag为真

        if(!flag)

        //表示flag为假

        2. 整型变量和零值的比拟:

        这中情况就很简略了,就是上面的写法:

        if(flag != 0)

        //表示flag为真

        if(flag == 0)

        //表示flag为假

        3. 浮点数与零值的比拟:

        对于浮点数与零值的比拟,就绝对复杂一些。因为计算机表示浮点数都有一个精度限制。对于超出了精度限制的浮点数,计算机

        会把它们的精度以外的小数部分截断。因此,原来不相等的两个浮点数在计算机中可能就酿成相等的了。

        float a = 2.111111112;

        float a = 2.111111118;

        理论上,这两个数是不相等的,但是在32为呆板上是相等的(原因:在32位呆板上,float保存6为小数)。

        所以,对于浮点数比拟,是这样规定的:如果两个同符号浮点数之差绝对值销毁或等于某一个可接受的误差(即精度),就以为

        每日一道理
    那蝴蝶花依然花开花落,而我心中的蝴蝶早已化作雄鹰飞向了广阔的蓝天。

        它们是相等的,否则就是不相等的。至于精度应根据详细要求而定。而不要直接用“==”或“!=”对两个浮点数停止比拟

        float sub = 0.0000001f;

        //自定义的精度

        if(abs(a - b) <= sub);

        //表示a == b;

        if(abs(a - b) > sub);

        //表示a != b;

        而与零值的比拟,当然就是上面的写法了:

        if(abs(a) <= sub);

        //表示a == 0;

        if(abs(a) > sub);

        //表示a != 0;

        注意:在实际的编程环境中,如果直接比拟浮点数和另一个数(整型或浮点数)是不是相等(==)或不等(!=),可能产生错误。

        至于其结果,可能依赖于详细的编译环境和平台,因为每个编译平台都有自己默许的精度,对于浮点数直接停止==和!=比拟

        采用的就是这个默许的精度,而不是按照内存中两个唯一某个bit不同来判断的。

        4. 指针变量与零值的比拟:

        指针变量的零值是“空值”(即为NULL),即不指向任何对象。

        所以指针变量与零值比拟的标准if语句如下:

        if(p == NULL)

        //p为空

        if(p != NULL)

        //p不为空

        虽然NULL的值与0雷同,但是两者意义不同。打开VC环境下的NULL定义:

    /* Define NULL pointer value */
    
    	#ifndef NULL
    	#ifdef  __cplusplus
    	#define NULL    0
    	#else
    	#define NULL    ((void *)0)
    	#endif
    	#endif

        也就是说NULL是定义的一个宏,这样即可区分整型与0值的比拟;

        如果使用上面的写法:

        if(p != 0)

        //表示flag为NULL

        if(p == 0)

        //表示flag为NULL

        当然,这样也不会错,但是我们会误以为p是整型变量。

        虽然这都是一些很小的方面,但是程序中难以查找的bug往往就是出现在这些细节的地方!

    文章结束给大家分享下程序员的一些笑话语录: 姿势要丰富,经常上百度!

    --------------------------------- 原创文章 By
    浮点数和变量
    ---------------------------------

  • 相关阅读:
    logback-spring.xml配置文件详解
    SpringBoot-Controller接收参数的几种常用方式
    spring boot配置定时任务设置
    SpringCloud 配置文件 application.yml和 bootstrap.yml区别
    ajax/get请求
    ajax封装2
    ajax封装1
    楼层特效
    旋转动画
    联动动画
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3102170.html
Copyright © 2020-2023  润新知