Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.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中的无穷大?_Java_Math_Floating Point_Ieee 754 - Fatal编程技术网

为什么-无穷大的平方根是+;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: 如果 第一个参数为负零,第二个参数小于零但不是有限的奇数整数,或

我尝试了两种不同的方法在Java中查找平方根:

Math.sqrt(Double.NEGATIVE_INFINITY); // NaN
Math.pow(Double.NEGATIVE_INFINITY, 0.5); // Infinity

为什么第二种方法不返回预期的答案,即
NaN
(与第一种方法相同)?

它只是按照
数学
中的描述进行操作

对于
Math.sqrt

如果参数为NaN或小于零,则结果为NaN

对于
Math.pow

如果

  • 第一个参数为负零,第二个参数小于零但不是有限的奇数整数,或
  • 第一个参数为负无穷大,第二个参数大于零但不是有限的奇整数
那么结果就是正无穷大

至于他们为什么做出这样的设计选择——你必须询问java的作者。

ANaN被返回(根据IEEE 754),以便在获得真正未定义的(中间)结果时继续计算。溢出发生后,返回一个无穷大,以便继续计算

这样的行为

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
的事实