pow(1,inf)== nan?

时间:2015-08-10 09:06:55

标签: c++ opengl glsl nvidia

我注意到我的一个计算着色器中出现了一些奇怪的行为,他们会意外地返回nan。 在调查时,我发现pow是罪魁祸首:

pow(1, inf) == NaN

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

  

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

是否为此输入定义了GLSL pow

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

2 个答案:

答案 0 :(得分:3)

@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

答案 1 :(得分:2)

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

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

此外,GLSL 不是 C ++。这可能与算术一样令人惊讶,因为虽然它显然不是同一种语言,但人们可以预期数学仍然有效,不能一个吗?

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

现在,使用推测正确的中间结果扩展上述表达式,正确的结果应该是+INF,因为log2(+INF) = +INF1*+INF仍然是{ {1}}和+INF 但是,标准并没有真正定义这一点。它只显式(un)定义零指数。