zoukankan      html  css  js  c++  java
  • float 浮点数与零值0比较大小 ZZ

    float x;

    千万不要写x==0;

    写出float x 与“零值”比较的if语句——一道面试题分析

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

    请写出 float  x 与“零值”比较的 if 语句: 
    const float EPSINON = 0.00001; 
    if ((x >= - EPSINON) && (x <= EPSINON) 
    不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。 

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

    出处:http://topic.csdn.net/t/20041126/10/3590118.html

    [结论]
    浮点数等值比较使用下式:
    #include 
    #include 
    fabs(a - b) < FLT_EPSILON

    三个EPSILON:
    FLT_EPSILON
    DBL_EPSILON
    LDBL_EPSILON


    为什么浮点数不能直接作“等值比较”?
    在以前看书或看文章就知道有这件事了。知道是因为“精度”,但一直没有真正想过问题的严重性。
    今天在易自考www.ezikao.com.cn看到一个帖子,顺便搜索了一下,测试结果让我信服了这条规则:
    易自考帖子:http://www.ezikao.com.cn/bbs_disp.asp?boardid=47&id=79506

    以下内容引用自林锐《高质量C/C++代码编写指南》

    4.3.3 浮点变量与零值比较
    ? 【规则4-3-3】不可将浮点变量用“==”或“!=”与任何数字比较。
    千万要留意,无论是float还是double类型的变量,都有精度限制。所以一定要避免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。
    假设浮点变量的名字为x,应当将 
    if (x == 0.0) // 隐含错误的比较
    转化为 
    if ((x>=-EPSINON) && (x<=EPSINON))
    其中EPSINON是允许的误差(即精度)。



    最好定义一个符号常量来做。#define EPSILON 1e-6


    也可以想一下,0.9无限循环不是等于1吗?
    如果正好某个值等于0.9循环,浮点数只能给出一个“确定”的值,那就会“做错题”。

     

    我参照这篇文章写了这个例子:
    #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?

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

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

    虽然这件事很值得郁闷,不过我还是很高兴又知道了点东西。



    关于EPSILON,可不是能随便定义的!
    而且应该能想到,double和float的EPSINON是不同的。
    定义成什么呢?不必你去定义了,ANSI C已经定义了这些常量:
    载入头文件
    #include <float.h>float.h里面有许多关于浮点类型的定义。
    如:
    FLT_EPSILON
    DBL_EPSILON
    LDBL_EPSILON

    查看include文件,在float.h头文件中有很多关于浮点数的宏定义:


    [quote]#define FLT_EPSILON                1.19209290E-07F
    #define LDBL_EPSILON                1.084202172485504E-19[/quote]
    (我们自己定义FLT_EPSILON一般定义为

    const int FLT_EPSILON=1e-6;就可以了。
    这两个宏定义可用来作为float、 long double趋0最小的判断值。即:
    #include <float.h>;
    double a, b; 

    if( abs(a-b) < FLT_EPSILON)

    曾经令我疑惑的是abs,a-b也是浮点数,而abs的原型是

    int abs(int a)

    对int取绝对值。

    float fabs(float a)

    fabs才是对float去绝对值,但是在实际运行汇总

    float  a1=-3.14;
        cout<<abs(a1)<<"    "<<abs(a1)<<endl;

    2个输出的结果是一样的。都是3.14.

    abs与fabs的区别应该是精度不同,fabs精度更大一些。

  • 相关阅读:
    Pwn-warmup_csaw_2016 writeup
    操作系统习题总结
    操作系统-存储器管理部分(待更新)
    树与二叉树之间的互相转换
    黑客攻防技术宝典-反病毒篇笔记(三)
    jaegeropentracing的Java-client完整分布式追踪链
    jaegeropentracing的Java-client
    IDEA2018.2版本注册
    Spring整合CXF webservice restful 实例
    带有WS-Security验证的webservice
  • 原文地址:https://www.cnblogs.com/zhoug2020/p/10625185.html
Copyright © 2011-2022 走看看