2017-07-06 82 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

我错了,这不是一个错误 –