float 浮点数与零值0比较大小 ZZ

float x;html

千万不要写x==0;面试

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

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

请写出 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++代码编写指南》spa

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>
.net

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");    code

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

    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

blog

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


[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精度更大一些。

相关文章
相关标签/搜索