Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not getting integer overflow in Clojure?

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?

like image 587
wrongusername Avatar asked Dec 29 '11 04:12

wrongusername


2 Answers

(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
like image 67
Gert Avatar answered Sep 30 '22 15:09

Gert


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
like image 40
Arthur Ulfeldt Avatar answered Sep 30 '22 15:09

Arthur Ulfeldt