Clojure整数溢出

cdm*_*kay 7 jvm clojure

我正在运行Clojure 1.4.0.为什么如果我添加Integer/MAX_VALUE1,我得到一个Long,但如果我添加Integer/MAX_VALUE自己,我得到一个例外?

=> (def one 1)
=> (class one)
java.lang.Integer
=> (def max-plus-one (+ Integer/MAX_VALUE one))
=> max-plus-one
2147483648
=> (class max-plus-one)
java.lang.Long

=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
java.lang.ArithmeticException: integer overflow (NO_SOURCE_FILE:0)
Run Code Online (Sandbox Code Playgroud)

它们不应该以同样的方式行事吗?为什么添加两个MAX_VALUE值会溢出但添加1不会?

我已经看到了这个问题,但他们的行为与我不同.

raj*_*ter 7

这很奇怪,我在Ubuntu 12.04 64bit上看到了与Clojure 1.4.0和Java(TM)SE运行时环境(版本1.7.0_06-b24)不同的结果:

user=> *clojure-version*
{:major 1, :minor 4, :incremental 0, :qualifier nil}
user=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
4294967294
user=> (type 1)
java.lang.Long
user=> (def max-plus-one (+ Integer/MAX_VALUE one))
#'user/max-plus-one
user=> max-plus-one
2147483648
user=> (type max-plus-one)
java.lang.Long
user=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
4294967294
Run Code Online (Sandbox Code Playgroud)

您始终可以检查clojure.core用于数字Java类,以查看功能的实现方式:

+运算符的实现:

(defn +
  "Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'"
  {:inline (nary-inline 'add 'unchecked_add)
   :inline-arities >1?
   :added "1.2"}
  ([] 0)
  ([x] (cast Number x))
  ([x y] (. clojure.lang.Numbers (add x y)))
  ([x y & more]
     (reduce1 + (+ x y) more)))
Run Code Online (Sandbox Code Playgroud)

添加longs的Java实现:

final public Number add(Number x, Number y){
    return num(Numbers.add(x.longValue(),y.longValue()));
}
Run Code Online (Sandbox Code Playgroud)

编辑:使用Clojure 1.2.1测试
我已经使用Clojure 1.2.1 进行了快速测试,并且使用该版本的Clojure,我得到了您的行为.

user=> *clojure-version*
{:major 1, :minor 2, :incremental 1, :qualifier ""}
user=> (def one 1)
#'user/one
user=> (class 1)
java.lang.Integer
user=> (def max-plus-one (+ Integer/MAX_VALUE one))
#'user/max-plus-one
user=> max-plus-one
2147483648
user=> (class max-plus-one)
java.lang.Long
user=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
java.lang.ArithmeticException: integer overflow (NO_SOURCE_FILE:0)
Run Code Online (Sandbox Code Playgroud)

我说你用Clojure 1.2.x进行了测试,而不是1.4.0.你的REPL中*clojure-version*的价值是多少?