如何检查Double值是否溢出?

时间:2016-05-24 19:06:25

标签: scala floating-point

我想检查是否为double值添加某些值是否超过Double limit。我试过这个:

 object Hello {
  def main(args: Array[String]): Unit = {
    var t = Double.MaxValue
    var t2 = t+100000000
    if(t2 > 0) {
      println("t2 > 0: " + t2)
    } else
      println("t2 <= 0: " + t2)
  }

}

我得到的输出是

t2 > 0: 1.7976931348623157E308

我真正想要的是总结数十亿个值并检查运行总和是否随时溢出。

2 个答案:

答案 0 :(得分:3)

问题的第一部分似乎源于对浮点数的误解。

  1. IEEE-754浮点数不会像某些有限大小的整数那样环绕。相反,它们在Double.PositiveInfinity“饱和”,代表数学(正)无穷大。 Double.MaxValue是双打的最大有限正值。之后的下一个DoubleDouble.PositiveInfinity。将任何双倍(Double.NegativeInfinityNaN除外)添加到Double.PositiveInfinity会产生Double.PositiveInfinity

    scala> Double.PositiveInfinity + 1
    res0: Double = Infinity
    
    scala> Double.PositiveInfinity - 1
    res1: Double = Infinity
    
    scala> Double.PositiveInfinity + Double.NaN
    res2: Double = NaN
    
    scala> Double.PositiveInfinity + Double.NegativeInfinity
    res3: Double = NaN
    
  2. 随着幅度的增加,浮点数越来越少。由于舍入错误,Double.MaxValue + 100000000评估为Double.MaxValueDouble.MaxValue100000000大得多,如果您尝试添加后者,前者会“吞并”后者。您需要将Double的{​​{1}}订单添加到math.pow(2, -52) * Double.MaxValue才能获得Double.MaxValue

    Double.PositiveInfinity
  3. 现在,你写了

      

    我真正想要的是总结数十亿个值并检查运行总和是否随时溢出。

    一种可能的方法是定义一个递归添加数字的函数,但如果运行总和是无穷大或scala> math.pow(2,-52) * Double.MaxValue + Double.MaxValue res4: Double = Infinity 则停止,并将结果包装在NaN中:

    Either[String, Double]

答案 1 :(得分:2)

在评论中回答您的问题:

  

实际上,我希望获得数十亿的总值,并检查总数是否随时溢出。你能告诉我一个检查方法吗?

如果总数溢出,结果将是无穷大(正或负)或NaN(如果在某些时候你添加了正负无穷大):最简单的方法是检查total.isInfinity || total.isNaN