Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Scala除以零会产生不同的结果_Java_Scala_Arithmetic Expressions_Divide By Zero - Fatal编程技术网

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

Java Scala除以零会产生不同的结果,java,scala,arithmetic-expressions,divide-by-zero,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

我对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
正如您在上面的示例中所看到的,根据除以零的方式,可以得到以下结果之一:

  • “java.lang.arithmetricException:/by zero”
  • “Double=NaN”
  • “Double=无穷大”

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

这完全取决于各种类型的零除法规则

0/0
是一个整数除以零(因为两个参数都是整数文本),这是抛出
java.lang.arithmetricException
所必需的

1.toDouble/0.toDouble
是一个带正分子的浮点除以零,计算为
+无穷大

0.0/0.0
是一个用零分子除以零的浮点数,计算为
+NaN


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

双精度
浮点
浮点值()可表示为标准中定义的
+无限
-无限
NaN

整数
固定数字
,它们没有任何方式明确表示无效数据,因此它们抛出
异常

对此的统一解决方案是在
Try
上使用
getOrElse
方法

Try(x/y).getOrElse(0)
如果只想在
算术异常
上恢复,可以使用
恢复
获取

Try(x/y).recover{ case _: ArithmeticException => 0 }.get
恢复
允许您将
故障
转换为
成功

您还可以使用
Try
to
选项
在不显示异常的情况下返回“无结果”

Try(x/y).toOption

您可以对类似的内容使用分部函数。例如:

object MyObject {
    def main(args: Array[String]) {

        println(safeDiv.isDefinedAt(1.0, 1.0)) // true
        println(safeDiv.isDefinedAt(1.0, 0.0)) // false
        println(safeDiv(1.0, 1.0))             // 1.0 
        println(safeDiv(1.0, 0.0))             // crash

    }

    def safeDiv: PartialFunction[(Double, Double), Double] = { 
        case(a,b) if b != 0.0 => a/b 

    }   
}
分部函数允许您检查函数是否为给定输入定义。在上面的例子中,我说过如果除数为0.0,则函数
safeDiv
没有定义。因此,您可以检查函数是否会在给定输入的情况下执行。无需进行检查,但是
safeDiv(1.0,0.0)
不会执行

部分函数是你的朋友,反对这样的东西:

scala> (1.0/0.0).toInt
res22: Int = 2147483647

我认为这与不同的数据类型有关。当执行不同但相关的计算时,请尝试始终使用相同的数据类型。例如:Double,Int,etcYou可能正在处理未知特征的数据,但在Scala这样的静态类型语言中,您并不是在处理未知类型的数据。@AlexeyRomanov我理解您的意思。不过,我想大多数人都会同意,这种方法容易出现一些非常肮脏的bug,而且在您编写的每一个算术运算中都非常繁琐。谢谢。你的回答很有帮助,因为它详细说明了可能的解决方案。我发现
Try(1.0/0.0)
将返回
Success(Infinity)
而不是
Failure
,并且
OrElse
不会返回。太好了。我想它会变得很方便