朋友之间的Int.MaxValue是什么?

时间:2017-04-26 18:05:18

标签: scala jvm language-design

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

为什么这个表达式会返回true

2 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:3)

回应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.这通常不被视为整数数据类型的失败。

如果您正在操作数量级不同的数字,并且也无法容忍舍入错误,那么您将需要考虑二进制数据表示的固有限制的数据结构和算法。一种可能的解决方案是使用具有较少指数位的浮点编码,从而限制最大值,但提供更高分辨率的是较不重要的位。有关更多详细信息,请查看: