2012-05-25 19 views
2

可能重複:
C++ double precision and rounding offGCC C/C++雙行爲

代碼:

int main(void) 
{ 
    double a = 12; 
    double b = 0.5; 
    double c = 0.1; 

    std::cout.precision(25); 
    std::cout << a << std::endl; 
    std::cout << b << std::endl; 
    std::cout << c << std::endl; 
    std::cout << a + b << std::endl; 
    std::cout << a + c << std::endl; 

    return 0; 
} 

輸出:

12 
0.5 
0.1000000000000000055511151 
12.5 
12.09999999999999964472863 

爲什麼GCC代表0.1和0.5不同?添加時,它們的表示方式不同。它看起來是0.5,整個數字與其他浮標不同。或者這只是在io庫中發生的事情? 是什麼導致了這種行爲?

+0

[相關](http://stackoverflow.com/questions/5098558/float-vs-double-precision)。 – iammilind

+1

雙打沒有無限精度。您分配的值不能完全使用雙精度來表示。 – MatthewD

+0

我澄清了我的問題。這不關乎精確性。 –

回答

5

正如了具有有限數量的位十進制數字只能精確地表示是10功率的總和的數字,二進制浮點數只能精確地代表是2

功率的總和的數字在這種情況下,0.1不能被表示爲2的冪的有限和,而0.512可以(0.5等於2 -112等於2 + 2 )。

作爲進一步的實例,0.75也可以精確地在二進制浮點數表示的,因爲它可以被表示爲2 -1 + 2 -2

+0

我看到.......... –

4

0.1不能用二進制精確表示,因爲它不是2的冪,而必須用一個確實真的非常接近的數字表示。這就是爲什麼學生被教會永遠不會使用==操作員在比較浮點數和銀行應用程序時幾乎總是將貨幣存儲爲兩個整數,即美元數量和便士數量。

+0

當然。但是這導致我也許會回答。 0.5存儲方式不同嗎?這真是我的問題。有時代碼不足以表達你的娛樂。 –

+2

@toor:0.5具有精確的二進制表示,但0.1不具有。 –

4

對這些問題的默認回答:

What every computer scientist should know about floating-point arithmetic

基本上,它的浮點編碼的不準確性。你有大約17位有效數字,並進行算術運算減少它們。

+0

我澄清了我的問題。這不關乎精確性。 –

+3

[閱讀器友好](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)版本的同一篇文章。 – Lundin

+0

這是 - 請參閱我上面的評論或閱讀論文。它歸結爲用有限數字來表示無限的一系列二進制數字。 –

0

尋找在這個例子中:在添加進行

12 
+ 
0.1000000000000000055511151 
= 
12.09999999999999964472863 

後,將所得的雙(12.0999...)具有朝向結果的小數部分被分配較低的精度值比原來的0.1000...值。小數部分必須改變以適應更大的整數量。