beginners

Shantanu 2025-11-09T10:39:00.564009Z

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+308M

Shantanu 2025-11-16T03:31:53.684949Z

Waited 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 πŸ™‚.

Alex Miller (Clojure team) 2025-11-19T17:15:46.774379Z

I answered in Ask Clojure, this is not a bug and is by design

πŸ‘ 1
Shantanu 2025-11-19T17:19:04.483969Z

Yup, saw it. Although I was curious as to why promotion for floating point numbers was decided to be skipped.

Alex Miller (Clojure team) 2025-11-19T17:19:14.543199Z

Double vs bigdecimal is not about scale (double is huge) but about precision. Vs long to biginteger which is about scale

Alex Miller (Clojure team) 2025-11-19T17:20:36.365529Z

Feels like the same case, but is not

πŸ‘ 2
adi 2025-11-09T10:56:38.079059Z

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 ... 
)

adi 2025-11-09T11:00:21.617259Z

Source for *' does not say it, but, looking at the shape of the code, I think this will also not auto-promote.

Shantanu 2025-11-09T11:04:00.752329Z

Maybe I'm looking in the wrong place 🀷.

Shantanu 2025-11-09T11:04:39.397609Z

In the addP of LongOps I see the logic for promotion.

adi 2025-11-09T11:05:09.878799Z

πŸ€·β€β™‚οΈ 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)
18446744073709551614N

Shantanu 2025-11-09T11:06:05.477309Z

Yeah, 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.

adi 2025-11-09T11:28:24.695029Z

That must be it...

Alex Miller (Clojure team) 2025-11-09T14:23:33.112659Z

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?

Shantanu 2025-11-09T14:56:19.063619Z

Nope.

Shantanu 2025-11-09T15:01:45.440549Z

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.

Shantanu 2025-11-09T16:05:16.653619Z

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)
##Inf

Wallysson Oliveira 2025-11-10T00:38:15.632789Z

I think this is a bug because the expected result would be that *' and +' autopromote.

Shantanu 2025-11-10T04:16:32.101659Z

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. 🀞.

πŸ‘ 1