Maybe I'm misunderstanding but I was expecting automatic promotion to BigDecimal when I added Double/MAX_VALUE twice. What am I getting wrong?
user=> (* 2 Double/MAX_VALUE)
##Inf
user=> (*' 2 Double/MAX_VALUE)
##Inf ;; I was expecting automatic promotion, so 3.5953862697246314E+308M.
user=> (+' Double/MAX_VALUE Double/MAX_VALUE)
##Inf ;; Automatic promotion here as well.
user=> (* 2 (bigdec Double/MAX_VALUE))
3.5953862697246314E+308MWaited for the Conj to be over. @alexmiller Can you confirm if this is indeed a bug? I'm currently working on https://github.com/jank-lang/jank/pull/588 in jank and would love to contribute to Clojure as well if this is indeed a bug π.
I answered in Ask Clojure, this is not a bug and is by design
Yup, saw it. Although I was curious as to why promotion for floating point numbers was decided to be skipped.
Double vs bigdecimal is not about scale (double is huge) but about precision. Vs long to biginteger which is about scale
Feels like the same case, but is not
Is this why? "does not auto-promote longs"
user=> (clojure.repl/source *)
(defn *
"Returns the product of nums. (*) returns 1. Does not auto-promote
longs, will throw on overflow. See also: *'"
;; ... snip ...
)Source for *' does not say it, but, looking at the shape of the code, I think this will also not auto-promote.
Yeah, I was expecting an implementation for addP here in the https://github.com/clojure/clojure/blob/6a4ba6aedc8575768b2fff6d9c9c7e6503a0a93a/src/jvm/clojure/lang/Numbers.java#L634 similar to how there is https://github.com/clojure/clojure/blob/6a4ba6aedc8575768b2fff6d9c9c7e6503a0a93a/src/jvm/clojure/lang/Numbers.java#L490 for the https://github.com/clojure/clojure/blob/6a4ba6aedc8575768b2fff6d9c9c7e6503a0a93a/src/jvm/clojure/lang/Numbers.java#L449.
Maybe I'm looking in the wrong place π€·.
In the addP of LongOps I see the logic for promotion.
π€·ββοΈ I don't know enough about how Java maths works...
user=> (* 2 Double/MAX_VALUE)
##Inf
user=> (*' 2 Double/MAX_VALUE)
##Inf
But, overflows with Longs...
user=> (* 2 Long/MAX_VALUE)
Execution error (ArithmeticException) at java.lang.Math/multiplyExact (Math.java:1032).
long overflow
user=> (*' 2 Long/MAX_VALUE)
18446744073709551614NYeah, so the https://github.com/clojure/clojure/blob/6a4ba6aedc8575768b2fff6d9c9c7e6503a0a93a/src/jvm/clojure/lang/Numbers.java#L494 for Long to BigInt is visible in the Clojure compiler code but I don't see anything similar for promotion from Decimal to BigDecimal.
That must be it...
I would expect *β to auto-promote, that is its purpose. My guess is that itβs the category crossing with long and decimal and the order these args come in. If you swap the args does it work?
Nope.
Am I looking at the correct code segments of the Clojure compiler above? Since in there I don't see the logic for promotion in the DoubleOps as can be seen in the LongOps.
This also didn't work:
user=> (*' 2.0 Double/MAX_VALUE)
##Inf
user=> (*' Double/MAX_VALUE 2.0)
##Inf
user=> (*' Double/MAX_VALUE 2.0M)
##Inf
user=> (*' 2.0M Double/MAX_VALUE)
##InfI think this is a bug because the expected result would be that *' and +' autopromote.
I asked the question https://ask.clojure.org/index.php/14752/support-for-automatic-promotion-to-bigdecimal-in-etc with a few more details and sneakily have asked if I can work on the fix for the Clojure side as well π. Hopefully I used the correct tags, etc. π€.