我尝试了两种不同的方法来在Java中找到平方根:
Math.sqrt(Double.NEGATIVE_INFINITY); // NaN
Math.pow(Double.NEGATIVE_INFINITY, 0.5); // Infinity
为什么第二种方式不能返回NaN
的预期答案(与第一种方式相同)?
答案 0 :(得分:48)
返回 NaN (在IEEE 754下),以便在获得真正未定义(中间)的结果时继续计算。返回 infinity ,以便在发生溢出后继续计算。
因此行为
Math.sqrt(Double.NEGATIVE_INFINITY); // NaN
是指定的,因为已知(很容易 并且很快 )已生成未定义的值;完全基于论证的标志。
然而评估表达式
Math.pow(Double.NEGATIVE_INFINITY, 0.5); // Infinity
遇到溢出和无效操作。然而,无效操作识别主要取决于确定第二个参数的准确程度。如果第二个参数是先前舍入操作的结果,则它可能不是 完全 0.5。因此,为了避免结果严重依赖于第二个参数的准确性,返回不太严重的确定,溢出的识别。
有关IEEE 754标准背后的一些推理的其他详细信息,包括返回标志值而不是生成异常的原因,可在
中找到。What Every Computer Scientist Should Know About Floating-Point Arithmetic (1991, David Goldberg),
是
的附录D.答案 1 :(得分:30)
它只是按Math
的{{3}}中描述的那样行事。
Math.sqrt
:
如果参数为NaN或小于零,则结果为NaN。
Math.pow
:
如果
- 第一个参数是负零,第二个参数小于零但不是有限的奇数,或
- 第一个参数是负无穷大,第二个参数大于零但不是有限的奇数,
然后结果是正无穷大。
至于他们为什么选择这种设计 - 你必须问问java的作者。