I am running Clojure 1.3.0 with La Clojure in IntelliJ IDEA while reading The Joy Of Clojure, and on section 4.1.3 (page 64), the authors demonstrate integer overflow with the following code:
(+ Integer/MAX_VALUE Integer/MAX_VALUE)
;=> java.lang.ArithmeticException: integer overflow
However, when I try it out on the REPL, I get instead
user=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
4294967294
user=> Integer/MAX_VALUE
2147483647
What is happening here? Why are my integers being added correctly instead of overflowing?
(edited) Clojure (at least 1.3.0) automatically converts the integer to a long if necessary. For more details about automatic boxing, promotion and primitive numeric type support in Clojure 1.3.0 check the Documentation for Clojure 1.3.0 Numerics.
The reason you don't get an overflow is because Clojure automatically converts the integer to a long, so (+ Integer/MAX_VALUE Integer/MAX_VALUE)
is adding two longs:
user> (type Integer/MAX_VALUE)
java.lang.Long
In Clojure all primative integers are primative longs and the documentation on the numerics page is refering to that. in 1.3 you just need bigger numbers to get your overflow.
user=> (+ Long/MAX_VALUE Long/MAX_VALUE)
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)
This important part is that older versions of clojure would have promoted to a big int automatically and it was decided that the cost of this was not worth the extremely rare cases where it is desired. if you really want promoting math use +'
user=> (+' Long/MAX_VALUE Long/MAX_VALUE)
18446744073709551614N
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With