2011-08-16 139 views
6

我剛剛從Peter Lawreys post得知這是有效的表達式,並且評估爲true爲什麼在Java中允許雙精度的任意精度?

333333333333333.33d == 333333333333333.3d 

我的問題是,爲什麼它允許有不能在雙表示雙面值,而不能代表整數文字是不允許的。這個決定是什麼理由


一個側面說明,我可以實際上觸發了一系列編譯錯誤的雙打文字:-)

99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999d 

所以只要我們在(最小值,最大值)範圍內,文字變得近似,但當超出這個範圍時,編譯器似乎拒絕接近它。

+5

你如何提出我們容易代表「如果你不接受0.1就可以」接近0.1的雙倍「? –

+0

好點。多麼明顯......:P – aioobe

回答

9

問題是,您可能輸入的極小數小數可以完全表示爲IEEE浮點數。所以,如果你刪除了所有非確切的常量,你會使用雙重文字非常笨重。大多數情況下,「假裝我們可以代表它」的行爲是非常有用的。

+0

好點!多麼明顯!感謝您指出。 – aioobe

+0

儘管這些表示在-MAX和MAX之間並不是均勻分佈的,所以對於某些人來說,「盡力而爲」表示比其他人好得多。你展示的例子恰好是非常糟糕的。 – Flexo

2

最主要的原因可能是Java根本無法知道何時您的精度不夠用,因爲沒有CPU操作代碼。

爲什麼沒有CPU標誌或類似的標誌?因爲數字的表示根本不允許。例如,即使像「0.1」這樣的簡單數字也沒有明確的表示。 0.1給你「00111111 10111001 10011001 10011001 10011001 10011001 10011001 10011010」(見http://www.binaryconvert.com/result_double.html?decimal=048046049)。

該值不是精確的0.1,而是1.00000000000000005551115123126E-1

所以即使對於這些「簡單」的情況下,代碼也不得不拋出異常。

+2

儘管我認爲可以精確表示小數,但不需要CPU操作代碼,這是可能的。 – Flexo

+0

確實如此,但速度會非常慢。那麼你的觀點是什麼? –