非确定性Math.pow(x,2)[Scala]

时间:2015-11-18 17:38:26

标签: java scala double precision non-deterministic

在我的代码中,我开始注意到相同的初始条件会输出不同的结果。

经过几个小时的狩猎,我发现了虫子发生的地方。

我有一个简单的函数,它需要一些参数,其中一个是vv是双倍的。 该函数内的一个计算是Math.pow(v, 2)

在编写了一些代码记录了该函数的所有输入以及该函数内的所有中间计算之后,我发现v总是等于-54.35178459279,但有时

Math.pow(-54.35178459279, 2) = 2954.116488421044

有时(看结尾3)

Math.pow(-54.35178459279, 2) = 2954.1164884210443

什么?发生了什么事?

我尝试在无限循环中运行Math.pow(-54.35178459279, 2)以查看它是否有时会提供不同的输出。好吧,它没有。

我到目前为止唯一的猜测是:

一个。我的调试器没有显示数字中的所有数字

湾即使调试器显示v s的相同表示形式,底层的scala double也略有不同。

对于那些真正想要一个例子的人来说,这是我能做的最好的事情:

val precision = 1000000000000.0
def step(v: Double) = {
  val newV = Math.round(calcV(v)*precision) / precision
  step(newV)
}

def calcV(v: Double) = Math.pow(v, 2)

得到一个线索:

scala> -54.35178459279 * -54.35178459279
res0: Double = 2954.1164884210443
scala> Math.pow(-54.35178459279, 2)
res0: Double = 2954.116488421044

0 个答案:

没有答案