Scala除以零会产生不同的结果

Ahm*_*dov 10 java scala arithmetic-expressions divide-by-zero

我对Scala处理除零的方式感到困惑.这是一个REPL代码片段.

scala> 1/0
java.lang.ArithmeticException: / by zero
  ... 33 elided

scala> 1.toDouble/0.toDouble
res1: Double = Infinity

scala> 0.0/0.0
res2: Double = NaN

scala> 0/0
java.lang.ArithmeticException: / by zero
  ... 33 elided

scala> 1.toInt/0.toInt
java.lang.ArithmeticException: / by zero
  ... 33 elided
Run Code Online (Sandbox Code Playgroud)

正如您在上面的示例中所看到的,取决于您如何除以零,您将获得以下之一:

  • "java.lang.ArithmeticException:/ by zero"
  • "双= NaN"
  • "Double = Infinity"

这使得调试非常具有挑战性,尤其是在处理未知特征的数据时.这种方法背后的原因是什么,甚至更好的问题,如何在Scala中以统一的方式处理除零?

Bat*_*eba 20

各种类型的零规则都归结为除法.

0 / 0是一个整数除零(因为两个参数都是整数文字),并且需要抛出一个java.lang.ArithmeticException.

1.toDouble/0.toDouble是一个浮点除以零,带有正分子,并且需要求值+Infinity.

0.0/0.0是一个浮点除零,零分子,并且需要求值+NaN.

第一个是Java和Scala约定,另外两个是IEEE754浮点的属性,这是Java和Scala都使用的.


Ram*_*jan 5

DoublesFloatsfloating-point的值(更这里),其可以被表示为+Infinity -InfinityNaN中定义IEEE 754标准。
Integersfixed numbers不具有的明确指示无效数据的方式,因此,他们抛出exceptions
的统一解决方案,这将是使用getOrElse方法上Try

Try(x/y).getOrElse(0)
Run Code Online (Sandbox Code Playgroud)

如果您只想恢复,ArithmeticException您可以使用recoverget

Try(x/y).recover{ case _: ArithmeticException => 0 }.get
Run Code Online (Sandbox Code Playgroud)

recover允许你转换FailureSuccess
您还可以使用TryOption返回“无结果”没有表现出异常

Try(x/y).toOption
Run Code Online (Sandbox Code Playgroud)