Doubles pollutes my BigDecimal math

I am writing a researcher for Mandelbrot Set. I need as much precision as possible so that I can zoom in as much as possible.

I noticed the unfortunate side effect of mixing double

and BigDecimal

s: they pollute the return type:

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

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

      

I expected the opposite. BigDecimals

, while potentially more accurate, should contaminate doubles.

Aside from calling manually bigdec

on every number that may touch BigDecimal

, is there a way to prevent automatic downgrade to double

when doing math on double

and BigDecimal

s?

+3


source to share


2 answers


Once you put a double

into the equation, you limit the amount of precision you can have. BigDecimal with a million decimal places is not right for you if the way you drew it is multiplied by something with about 15 significant digits. You can boost the result to BigDecimal, but you've lost a ton of precision, whether you like it or not. Therefore, Clojure's promotion rules make it obvious to you by returning a double instead of the high-precision BigDecimal.



See for example http://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#BigDecimal-double- for an explanation why it's a bad idea to convert doubles to BigDecimals, implicitly or explicitly ...

+9


source


This is not really a bug, although it at least looks wrong. To show more clearly how this leads to incorrect searches, compare these expressions:

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

      



At this time, you will most likely need, in your opinion, to ensure that you only use large decimal places in your program. It will likely be limited to I / O functionality, and any constants you enter need an M

end. Adding prerequisites to functions will probably help catch some cases.

+3


source







All Articles