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

相關文章
相關標籤/搜索