为什么Long.MaxValue适合Double而<Long.MaxValue不适合

Ram*_*mon 4 scala

我知道有一个简单的答案,但它让我感到困惑.

为什么Long.MaxValue可以存储在Double中并以longValue形式返回,但较小的Long会丢失精度.

我原本预计在53位之后会失去精度?这里发生了什么

scala> val x:Double = Long.MaxValue  // x: Double = 9.223372036854776E18    (9223372036854775807)
scala> x == Long.MaxValue            // Boolean = true
scala> x.longValue == Long.MaxValue  // Boolean = true
scala> val y = 1234567890123456789L  // y: Long = 1234567890123456789  // less than Long.MaxValue
scala> y < x                         // Boolean = true
scala> val z:Double = y              // z: Double = 1.23456789012345677E18
scala> z == y                        // Boolean = true
scala> z.longValue == y              // Boolean = false  // why ? MaxValue fits in the Double
scala> z.longValue                   // 1234567890123456768 <-- loss of 21
Run Code Online (Sandbox Code Playgroud)

dhg*_*dhg 5

这不是"适合"的问题.双打本身就是不精确的.有些值会被准确表示,有些则不会.看起来你找到了一个可以(你的x)和一个不能(你的y).

你所选择的价值并不是特别的.这里有类似的行为,较小的值明显"适合"双打:

val a = 1.1        // a: Double = 1.1
a == 1.1           // true

val b = 2.2        // b: Double = 2.2
b == 2.2           // true

val c = 1.1 + 2.2  // c: Double = 3.3000000000000003
c == 3.3           // false
Run Code Online (Sandbox Code Playgroud)