Clojure Math/sqrt 大整数精度

Clojure Math/sqrt precision on big integers

为什么下面的 Clojure 代码会打印 "true"?

(请注意最后一位数字不同)

(== (Math/sqrt 10252519345963644753026N)
    (Math/sqrt 10252519345963644753025N))

不确定这个问题是仅与 Clojure 相关,还是也适用于其他语言(Java 的 BigInteger?)。

打印结果:

(str (Math/sqrt 10252519345963644753026N) " "
     (Math/sqrt 10252519345963644753025N))

1.01254725055E11 1.01254725055E11

JavaMath.sqrt函数

  • 接受一个double参数并且
  • returns 一个 double 结果。

正如各种评论所暗示的那样,这导致的转换失去了区分数字的精度。事实上,转换为 double 就是这样做的:

(= (double 10252519345963644753026N)
   (double 10252519345963644753025N))
;true

A double 具有 53 位精度。由于 10 位大约是 3 个十进制数字,因此这大约是 16 个十进制数字的精度。您的号码长度为 23 位,因此最后几位数字在转换中丢失了。