Java 大整数上的Clojure Math/sqrt精度

Java 大整数上的Clojure Math/sqrt精度,java,math,clojure,sqrt,Java,Math,Clojure,Sqrt,为什么下面的Clojure代码打印“true” (请注意,最后一位数字不同) 不确定这个问题是否只与Clojure有关,或者它是否也适用于其他语言(Java的BigInteger?) 打印它们会导致: (str (Math/sqrt 10252519345963644753026N) " " (Math/sqrt 10252519345963644753025N)) 1.01254725055E11 1.01254725055E11 JavaMath.sqrt函数 接受一个dou

为什么下面的Clojure代码打印“true”

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

不确定这个问题是否只与Clojure有关,或者它是否也适用于其他语言(Java的BigInteger?)

打印它们会导致:

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

1.01254725055E11 1.01254725055E11

Java
Math.sqrt
函数

  • 接受一个
    double
    参数并
  • 返回一个
    double
    结果
正如各种评论所指出的,这导致的转换失去了区分数字的精度。事实上,转换为
double
可以:

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


双精度具有53位精度。因为10位大约是3位十进制数字,所以这大约是16位十进制数字的精度。您的数字长度为23位,因此最后几位在转换过程中丢失。

您是否尝试分别打印这两个数字的sqrt操作结果?似乎它们可能会失去足够的精度,以达到有限精度。Math.sqrt使用只有15位精度的double。比这更多的数字可以使示例看起来更精确。我不知道Clojure,但在调用下面的平方根操作之前,
Math/sqrt
几乎肯定会将其参数转换为双精度。作为双倍,您提供的两个输入值是相同的(因此,输出当然也是相同的)。打印不一定是检查值的可靠方法()
(= (double 10252519345963644753026N)
   (double 10252519345963644753025N))
;true