Math.pow
的ECMAScript规范具有以下特殊规则:
- 如果x < 0和x是有限的,y是有限的,y不是整数,结果是NaN。
(http://es5.github.com/#x15.8.2.13)
因此Math.pow(-8, 1 / 3)
提供NaN
而不是-2
这条规则的原因是什么?是否存在某种更广泛的计算机科学或IEEE推理这一规则的原因,或者它只是TC39 / Eich曾经做过的一种选择?
感谢Amadan与我的交流,我想我现在理解这个推理。我想为了后代而扩展我们的讨论。
我们采用以下示例:Math.pow(823543, 1 / 7)
会产生6.999999999999999
,但它确实应该是7
。这是由于1 / 7
必须首先转换为十进制表示0.14285714285714285
而被引入的不准确性,该十进制表示被截断并失去精度。当我们处理正数时,这不是一个很糟糕的问题,因为我们仍然得到一个非常接近实际结果的结果。
但是,一旦我们走入负面世界,我们就会遇到问题。如果JavaScript引擎尝试计算Math.pow(-823543, 1 / 7)
,则首先需要将1 / 7
转换为小数,因此它实际上是计算Math.pow(-823543, 0.14285714285714285)
,实际没有真正的答案< / em>的。在这种情况下,它可能必须返回NaN
,因为它找不到实数,即使真正的答案应该是-7
。此外,寻找接近实数的复数来做出“最佳猜测”可能涉及一定程度的复杂性,他们不希望JS引擎在数学领域拥有。
我的猜测是由于考虑到浮点数的精度损失导致他们得出这样的规则,即非整数幂的负数应始终为NaN
- 基本上是因为非由于精度损失,整数幂可能会给出一个复数,即使它不应该,并且可能没有好的方法可以从中恢复。
有了这个,我相当满意,但我确实欢迎进一步的信息。
答案 0 :(得分:4)
我认为,因为这些情况导致结果进入复杂的水域,ECMAScript没有配备虚数。具体来说,您的示例应该会产生接近1 + 1.732i
的结果,以及其他结果。 (事实上,-2也是一个可能的结果是除了这一点 - 这是一个意外而不是规则。)
答案 1 :(得分:0)
您可以使用辅助功能。
在迅速中我遇到了类似的情况。以下是为您提出的解决方案
func checkSquareRoot(x: Double, y: Double) -> Double {
let result = pow(x, y)
if x > 0 {
return result
} else {
return -1 * pow( -x, y)
}
}