为什么-无穷大的平方根是+;Java中的无穷大?
我尝试了两种不同的方法在Java中查找平方根:为什么-无穷大的平方根是+;Java中的无穷大?,java,math,floating-point,ieee-754,Java,Math,Floating Point,Ieee 754,我尝试了两种不同的方法在Java中查找平方根: Math.sqrt(Double.NEGATIVE_INFINITY); // NaN Math.pow(Double.NEGATIVE_INFINITY, 0.5); // Infinity 为什么第二种方法不返回预期的答案,即NaN(与第一种方法相同)?它只是按照数学中的描述进行操作 对于Math.sqrt: 如果参数为NaN或小于零,则结果为NaN 对于Math.pow: 如果 第一个参数为负零,第二个参数小于零但不是有限的奇数整数,或
Math.sqrt(Double.NEGATIVE_INFINITY); // NaN
Math.pow(Double.NEGATIVE_INFINITY, 0.5); // Infinity
为什么第二种方法不返回预期的答案,即
NaN
(与第一种方法相同)?它只是按照数学
中的描述进行操作
对于Math.sqrt
:
如果参数为NaN或小于零,则结果为NaN
对于Math.pow
:
如果
- 第一个参数为负零,第二个参数小于零但不是有限的奇数整数,或
- 第一个参数为负无穷大,第二个参数大于零但不是有限的奇整数
Math.sqrt(Double.NEGATIVE_INFINITY); // NaN
指定,因为已知(容易地和快速地)已生成未定义的值;完全基于论点的符号
然而,对表达式的评估
Math.pow(Double.NEGATIVE_INFINITY, 0.5); // Infinity
遇到溢出和无效操作。然而,无效操作识别在很大程度上取决于第二个参数的确定是否准确。如果第二个参数是先前四舍五入操作的结果,则它可能不完全是0.5。因此,返回不太严重的确定,即溢出识别,以避免结果严重依赖于第二个参数的准确性
有关IEEE 754标准背后的一些推理的其他详细信息,包括返回标志值而不是生成异常背后的推理,请参阅
,
这是本手册的附录D
.我同意,但在使用不同的方法时不应该前后矛盾,尤其是在数学方面,必须有一个标准答案,不是吗?在我看来,第二种方法是返回错误的答案。从我个人的角度来看,两者都是错误的。您应该抛出一个异常,而不是返回像Nan或Infinity这样的值。@Pratik:
Math.pow()
的返回值与pow()
的C标准定义一致。似乎它们都符合IEEE754对操作的定义,但我手头没有标准的副本。IEEE 754的设计者们有非常详细的理由解释为什么事情是这样的,尽管不是凡人都能理解。@Jeroenmoster是的,我也想到过IEEE 754,但我不知道该标准是否也定义了实际操作。如果有人可以访问它,最好能从那里获得更多的信息。@Pratik:你只能这样说,因为你知道第二个论点是准确的。浮点规范必须考虑到第二个参数是近似值(估计值或先前操作的结果)的可能性,因此当肯定发生溢出时,可能只发生了一个无效的操作。@Aziuth:Math.sqrt和Math.pow的行为都是完全定义的,即使是负参数,“未定义的行为”也不是Java从C借用的概念(幸运的是)。Java在某些特定情况下具有C标准所称的实现定义和未指定的行为,但没有比这更糟的。啊,其中一个问题是“为什么设计人员,以这种方式设计它?我会完全不同的方式设计它!”。除了设计师之外,任何人都无法客观地回答这些问题。@Aziuth:IEEE754中没有未定义的内容;还有一个很好的理由,因为浮点是实数的不精确表示。请参阅了解更多详细信息。@AndrewSavinykh:我不敢苟同-IEEE754经过深思熟虑,不仅解决了40年前非常重要的效率问题,而且有时还需要能够在出现溢出和无效操作的情况下继续计算。请参阅,其中对Python提出了几乎完全相同的问题。事实证明,IEEE 754中没有规定这种行为,但这种遗漏要么是偶然的,要么是因为IEEE 754的人认为这很明显,不需要规范。另请参见:如果第二个参数不完全是0.5,那么得到的无穷大的复相位仍然不接近π*N,所以从数学上讲,它仍然是无效的运算(对于R→R函数)。因此,这似乎不能很好地解释为什么它不能生成NaN。@Ruslan:我不同意。如果第二个参数正好是2/3,作为~0.6667传入,那么正确的返回值是溢出而不是NaN。这取决于分支切割的选择。。。他们可以选择从中得到一个复杂的结果(例如,directedfinity[-0.499999998186198+0.8660254038891585*I]
),然后返回NaN。我想他们选择了,如果有机会得到一个真正的结果,那么它应该被返回……我觉得这里的论点有问题。特别是,它缺少一个解释(a)为什么第二个参数的可能的不精确性产生了差异(为什么我们应该考虑<代码> PoW(-INF,0.5 +ε)<代码> > <代码> INF而不是<代码> NAN/<代码>?和(b)解释<代码> -INF < /代码>的特殊性:<代码> POW(-10,y)为任何非整数有限y
提供一个nan
。我认为更可能的是,基本原理仅仅来自于pow(-0.0,y)
的行为,保持对称性pow(1/x,y)=1/pow(x,y)
,以及1/-0.0
是