2017-07-06 83 views
3

我正在寫一個Mandelbrot集探險家。我需要儘可能的精確,以便儘可能地放大。雙打污染我的BigDecimal數學

我注意到混合double S和BigDecimal S的不幸的副作用:他們「污染」返回的類型:

(type (* 1M 2)) 
=> java.math.BigDecimal 

(type (* 1M 2.0)) 
=> java.lang.Double 

我預期相反。可能更精確的BigDecimals應該會污染雙打。

除了手動調用每一個可能接觸了BigDecimalbigdec,是否有阻止自動降級到doubledouble S和BigDecimal在做數學運算時的方法嗎?

+0

聽起來像是我的一個bug –

+0

nope,不是一個錯誤。這是故意的 –

+0

對於將來閱讀此內容的人,請注意,我的解決問題不是源於缺乏小數精度。我對Mandelbrot算法的最大迭代太低。我把它從50提高到了200,現在即使是雙精度也能提供相當數量的縮放。 – Carcigenicate

回答

9

一旦您將double引入到等式中,就會限制您可能具有的精度。一個精確到百萬位小數的BigDecimal對你來說是沒有用的,如果你把它的方式乘以僅有15個有效數字的東西。您可以將結果提升爲BigDecimal,但無論您是否喜歡,都會失去大量精度。因此,Clojure的推廣規則通過給出一個double而不是高精度的BigDecimal來讓你明白這一點。

例如,請參閱http://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#BigDecimal-double-以解釋爲什麼隱式或顯式地將雙打轉換爲BigDecimals是一個壞主意。

+0

啊,這是有道理的。謝謝。這也許可以解釋爲什麼儘管在任何地方使用Bigdecimal,我仍然會陷入我無法放大的硬邊界。現在我只需要找出我在哪裏投擲一個BigDecimal的雙精度,這樣就限制了我的精度。 – Carcigenicate

3

這實際上並不是一個錯誤,儘管它至少看起來錯了。爲了更清楚地說明如何這會導致錯誤的答案,尋找比較這些表達式:

user> (* 2.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001M 1.0) 
2.0 
user> (* 2.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001M 1.0M) 
2.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010M 

暫且你可能會需要,你的建議,確保你只在你的程序中使用大小數。它可能僅限於IO功能,並且您引入的任何常量最終都需要M。爲功能添加先決條件也可能有助於捕捉某些情況。

+0

我錯了,這不是一個錯誤 –