朋友之间Int.MaxValue是什么?

What's Int.MaxValue between friends?

Scala 中 int、float 和 long 的最大值为:

Int.MaxValue = 2147483647

Float.MaxValue = 3.4028235E38

Long.MaxValue = 9223372036854775807L

来自 Scala 编译器的作者,Keynote, PNW Scala 2013,幻灯片 16 What's Int.MaxValue between friends?

val x1: Float = Long.MaxValue
val x2: Float = Long.MaxValue - Int.MaxValue
println (x1 == x2)

// NO WONDER NOTHING WORKS

为什么这个表达式 return true?

一个Float是一个4字节的浮点值。同时,Long 是一个 8 字节的值,而 Int 也是一个 4 字节的值。然而,数字以 4 字节浮点值存储的方式意味着它们只有大约 8 位精度。因此,无论最低 4 个有效字节(另外 9-10 个数字)的值如何,它们甚至没有能力存储 Long 的 4 个最高有效字节(大约 9-10 个数字)。

因此,两个表达式的 Float 表示是相同的,因为不同的位低于 Float 的分辨率。因此这两个值比较相等。

呼应 Mike Allen 的回答,但希望提供一些额外的上下文(本来可以将其作为评论而不是单独的答案,但 SO 的声誉功能不允许我这样做)。

整数的最大取值范围定义为 0 到 2^n(如果它是无符号整数)或 -2^(n-1) 到 2^(n-1)(对于有符号整数)其中 n 是底层实现中的位数(在本例中为 n=32)。如果您希望用带符号的值表示大于 2^31 的数字,则不能使用 int。带符号的长整数最多可以工作 2^63。对于任何大于此的值,带符号的浮点数可以达到大约 2^127。

另一件需要注意的事情是,这些分辨率问题仅在存储在浮点数中的值接近最大值时才生效。在这种情况下,减法运算导致真值发生变化,比第一个值小许多个数量级。浮点数不会舍入 100 和 101 之间的差异,但它可能会舍入 10000000000000000000000000000 和 10000000000000000000000000001 之间的差异。

小值也是如此。如果将 0.1 转换为整数,则恰好为 0。这通常不被认为是整数数据类型的失败。

如果您对大小相差很多个数量级的数字进行运算,并且无法容忍舍入误差,则您需要能够解决二进制数据表示的固有局限性的数据结构和算法。一种可能的解决方案是使用具有较少指数位的浮点编码,从而限制最大值但提供更高分辨率的是较低有效位。有关更多详细信息,请查看: