Scala中Long和Double之间的转换和比较

时间:2017-05-17 06:20:42

标签: scala

我正在使用Scala AnyVal类型并且无法解读以下内容:我将Long.MaxValue转换为Double并返回Long。由于Long(64位)可以保存比Double尾数(52位)更多的数字,我预计此转换会使某些数据丢失,但不是这样的情况:

Long.MaxValue.equals(Long.MaxValue.toDouble.toLong) // is true

我认为Long.MaxValue.toDouble.toLong中可能存在一些魔法/优化,以至于转换并非真正发生。所以我也试过了:

Long.MaxValue.equals("9.223372036854776E18".toDouble.toLong) // is true

如果我评估表达式"9.223372036854776E18".toDouble.toLong,则会给出:

9223372036854775807

这真让我烦恼,最后4位数似乎只是突然冒出来了!

2 个答案:

答案 0 :(得分:3)

首先:像往常一样有这样的问题,Scala没有什么特别之处,所有现代语言(我所知道)都使用IEEE 754浮点(至少在实践中,如果语言规范不是这样的话)需要它)并且行为相同,只是使用不同的类型和操作名称。

是的,数据丢失了。如果您尝试例如(Long.MaxValue - 1).toDouble.toLong,您仍会获得Long.MaxValue。您可以在Long找到下一个最小的someDouble.toLong,如下所示:

scala> Math.nextDown(Long.MaxValue.toDouble).toLong
res0: Long = 9223372036854774784
  

如果我评估表达式"9.223372036854776E18".toDouble.toLong,则会给出:

9223372036854775808
     

这真让我烦恼,最后4位数似乎只是突然冒出来了!

你可能意味着92233720368547758079.223372036854776E18当然实际上大于它:它代表9223372036854776000。但是,如果您使用大于Double的任何其他Long.MaxValue,您将获得相同的结果,例如1E30.toLong

答案 1 :(得分:0)

请注意,Scala中的Double和Long值相当于double和long的原始类型。

Long.MaxValue.toDouble的结果实际上比Long.MaxValue更大,原因是,该值是四舍五入的。下一次转换,即Long.MaxValue.toDouble.toLong是"舍入"回到Long.MaxValue

的值