7

我在阅读The Joy Of Clojure时在 IntelliJ IDEA 中使用 La Clojure 运行 Clojure 1.3.0 ,在第 4.1.3 节(第 64 页)中,作者使用以下代码演示了整数溢出:

(+ Integer/MAX_VALUE Integer/MAX_VALUE)
;=> java.lang.ArithmeticException: integer overflow

但是,当我在 REPL 上试用它时,我得到了

user=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
4294967294

user=> Integer/MAX_VALUE
2147483647

这里发生了什么?为什么我的整数被正确添加而不是溢出?

4

2 回答 2

8

(已编辑) Clojure(至少 1.3.0)会在必要时自动将整数转换为长整数。有关 Clojure 1.3.0 中自动装箱、提升和原始数字类型支持的更多详细信息,请查看Clojure 1.3.0 Numerics 文档

没有溢出的原因是因为 Clojure 自动将整数转换为长整数,因此(+ Integer/MAX_VALUE Integer/MAX_VALUE)添加两个长整数:

user> (type Integer/MAX_VALUE)
java.lang.Long
于 2011-12-29T05:51:36.790 回答
8

在 Clojure中,所有原始整数都是原始长整数,数字页面上的文档引用了它。在 1.3 中,您只需要更大的数字即可溢出。

user=> (+ Long/MAX_VALUE Long/MAX_VALUE)
ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)

这个重要的部分是旧版本的 clojure 会自动提升为大 int 并且决定这样做的成本不值得在极少数情况下需要它。如果你真的想推广数学使用+'

user=> (+' Long/MAX_VALUE Long/MAX_VALUE)
18446744073709551614N
于 2011-12-30T02:27:45.030 回答