2013-03-05 77 views
0

請解釋輸出不同情況float和double輸出

#include<stdio.h> 
int main() 
{ 
    float a=5.9; //a=0.9 
    if (a==5.9) 
     printf("Equal"); 
    else if (a<5.9) 
     printf("Less than"); 
    else 
     printf("Greater than"); 
    return 0; 
} 

當一個是5.9的輸出「大於」,當是0.9輸出爲「小於」。爲什麼?

+3

這一切都在這裏:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – 2013-03-05 01:03:31

+0

你知道如何寫基數2的5.9嗎? – perreal 2013-03-05 01:03:34

+0

浮點數101 – 2013-03-05 01:04:31

回答

0

浮點數本質上是不精確的。快速介紹一下,你可以在這裏閱讀一下。 http://floating-point-gui.de/errors/comparison/

有關有效比較策略的一些建議,請參閱此帖。 What is the most effective way for float and double comparison?

+0

這並不回答這個問題,因爲它沒有解釋結果。它主張放棄使用浮點來進行精確或受控的算術運算,並提出一種不適用於所有應用的全面比較技術。 – 2013-03-05 01:08:17

0

當比較浮點數時,最好避免'=='。

這是因爲某些值無法在沒有某些精度損失的情況下正確存儲。

因此,最好是說:

if(fabs(a-5.9) < .0001) { 
    // 'EQUAL' or at least near enough! 
} 

我知道這需要更多的計算,但它會表現你期望的方式。

+0

雖然你的建議通常是有幫助的,但浮動和雙重之間沒有來回轉換,因此沒有信息真正丟失。由於這些是字面值,因此它們沒有進行正確的比較,因爲它們的類型有所不同,即將雙打和花車進行比較。 – Rapptz 2013-03-05 01:12:31

+2

這並沒有回答這個問題,因爲它沒有解釋結果。它主張放棄使用浮點來進行精確或受控的算術運算,並提出一種不適用於所有應用的全面比較技術。 – 2013-03-05 01:14:27

+0

永遠不要使用等於浮點數適用於幾乎所有的應用程序,主要例外是那些您正在測試浮點單元(Hauser等)的情況。你如何得到相同的代碼當然,這取決於應用程序和數字的範圍等.OP開始時打破了這個規則,爲此回答+1,然後OP使用float來加倍轉換,可能不會知道除非另有說明,否則C使用雙精度浮點數(對於hardcodings更改爲5.9F可能會改變結果)。 – 2013-03-05 01:21:11

0

由於十進制二進制轉換,0.9表示爲功率的總和2^-1:

0.9 - (0.5 + 0.25 + 0.125)= 0.025

但是0.025不是一個確切的功率2^-1。因此,您需要以相同的精度在比較中表示兩個數字。由於float和double具有不同的精度,所以它們比較不等。

3

在C中,文字「5.9」的類型爲double並且由共同的編譯器轉換爲5.9000000000000003552713678800500929355621337890625,因爲它們使用的二進制IEEE-754浮點數,並且該號碼是值表示爲一個double最接近5.9。您的代碼使用該值初始化float。這需要將double轉換爲float,結果爲5.900000095367431640625,因爲那是最接近double值的float值。顯然,後者比前者大,這就是爲什麼你的輸出是「大於」。

使用.9,文字「.9」被轉換爲double 0.90000000000000002220446049250313080847263336181640625。然後double轉換爲float 0.89999997615814208984375,這明顯小於double

+0

你正在假設一個舍入模式。 IEEE支持三種模式,舍入和舍入到零將使得數量爲5.8的東西相等仍然會失敗,但是不足以通過。確實,我們通常使用四捨五入,在原始轉換過程中尾數的lsbit加1,在一種或兩種情況下,存儲的數字略大於5.9。 – 2013-03-05 01:51:28

+2

@dwelch:IEEE 754規定了四種模式(圓到最近,圓到零,圓對無窮,圓對負無窮)。舍入爲最近的是共同模式,並且可以從問題中報告的行爲中推斷出圓到最近使用的行爲,因爲雙5.9附近(當轉換爲浮動時)和雙附近0.9。向下取整。其他四捨五入模式都不會產生這種行爲。對有效數字的LSB(不是尾數)進行四捨五入或加1都不是常見的默認模式。 – 2013-03-05 01:54:42