pow(1, inf) == 南?

Posted

技术标签:

【中文标题】pow(1, inf) == 南?【英文标题】:pow(1, inf) == nan? 【发布时间】:2015-11-02 03:12:53 【问题描述】:

我注意到我的一个计算着色器中有一些奇怪的行为,它们会意外返回 nan。 仔细调查后,我发现pow 是罪魁祸首:

pow(1, inf) == NaN

从C/C++ 的角度来看,我希望pow(1, inf) == 1

pow(+1, exponent) 对任何指数都返回 1,即使指数为 NaN

是否为此输入定义了 GLSL 的 pow

我只在规范中发现了base < 0base == 0 && exponent <= 0 的常见例外情况。

【问题讨论】:

1/0,嗯?被零除?无穷大似乎是正确的结果,而 NaN 作为无穷大的力量是不可能的。 @Vallentin:我只能告诉你我所看到的。 1/0 没有编译器错误(或警告)以及来自 pow 的 1 的结果。如果你有更好的方法create INF inside GLSL 告诉我。 除以零不需要抛出错误,因为无穷大是可接受的结果。因此 x^infinity 再次等于预期的 NaN。我的意思是,我看不出问题出在哪里,因为结果是有道理的。 @Vallentin 从数学的角度来看,我希望 1^infinity 为 1,x^infinity 为 0 1 为无穷大。 NaN 恕我直言的唯一地方是负数的无穷次幂。 @Nobody 从数学的角度来看,1^Infinity 不是 1。mathforum.org/library/drmath/view/56006.html 【参考方案1】:

@Damon's answer 很接近,但从规范中复制了一个错误:

pow(x, y) == exp2(x *  log2 (y))

x 和 y 交换了。应该是

pow(x, y) == exp2(y *  log2 (x))

(测试例如pow(2, 3)

使用我们得到的正确公式

pow(1, inf) == exp2(inf * log2(1)) == exp2(inf * 0) == exp2(nan) == nan

【讨论】:

【参考方案2】:

虽然计算着色器有点暗示您使用的 GPU 和 GLSL 版本 (> 1.30) 可以执行 IEEE 兼容的浮点数学运算,但不幸的是,这并不是您认为理所当然的事情。所以...这里是龙。

您从 C++ 的角度引用 C++ 参考的推理是合理且正确的,但它省略了一个小而重要的句子“如果实现支持 IEEE 浮点运算 (IEC 60559),”时间>。这个小句子强调它既不是 C++ 要求(只是巧合,因为 IEEE 754 要求它,通常 C++ 实现符合 IEEE),也不是严格保证(完全允许实现 IEEE 754 的 C++ 实现。

此外,GLSL 不是 C++。这可能会让算术感到惊讶,因为尽管它显然不是同一种语言,但人们可以期望数学仍然可以正常工作,不是吗?

嗯,不。 pow(x, y) 在 GLSL 中被定义为 exp2(x*log2(x))(尽管在线手册页所基于的 8.2 没有明确说明)。它继承了 4.7.1 中所述的上述表达式的精度。没有说明pow(1, x) 等于1

现在,用可能正确中间结果扩展上述表达式,正确的结果应该是+INF,因为log2(+INF) = +INF1*+INF仍然是+INF,和@987654330 @. 但是,标准并没有真正定义这一点。它仅显式(取消)定义零指数。

【讨论】:

刚刚在spec 中偶然发现了这个确切的 (exp2(x*log2(y))) 段落。该死的,只是另一件事要绊倒。 现在我想起来了,我意识到你的回答解释了为什么在 GLSL 中使用 pow(1, inf) == INF,但没有解释为什么它是我的问题中的 NaN。

以上是关于pow(1, inf) == 南?的主要内容,如果未能解决你的问题,请参考以下文章

C中的几个复杂的指数运算返回inf? [复制]

顶点最短路径(弗洛伊德算法)

为啥 (inf + 0j)*1 评估为 inf + nanj?

区分“inf”和“-inf”

prim算法

一种检测 NaN、NA、Inf、-Inf 等的功能?