战俘(1,信息)==南?
pow(1, inf) == nan?
我注意到我的一个计算着色器出现了一些奇怪的行为,它们 return 出乎意料。
在仔细调查时,我发现 pow
是罪魁祸首:
pow(1, inf) == NaN
从 C/C++ 的角度来看,我希望 pow(1, inf) == 1
:
pow(+1, exponent) returns 1 for any exponent, even when exponent is NaN
是否为此输入定义了 GLSL 的 pow
?
我只在规范中找到 base < 0
和 base == 0 && exponent <= 0
的常见例外情况。
虽然计算着色器有点暗示您使用 GPU 和 GLSL 版本(> 1.30)来执行符合 IEEE 的浮点数学运算,但这不是您可以想当然的事情,不幸的是。所以...这里是龙。
你从C++的角度引用C++参考的推理是合理和正确的,但是它省略了一个小而重要的句子:"If the implementation supports IEEE floating-point arithmetic (IEC 60559),"。这个小句子强调它既不是 C++ 要求(只是巧合,因为 IEEE 754 要求它,而且 通常 C++ 实现符合 IEEE),也不是严格保证(它是完全允许 C++ 实现 而不是 实现 IEEE 754)。
此外,GLSL 不是 C++。对于算术,这可能会让人感到惊讶,因为虽然它显然不是同一种语言,但人们可以期望数学仍然有效,不是吗?
嗯,不。 pow(x, y)
在 GLSL 中被定义为(虽然在线手册页所基于的 8.2 没有明确说明)为 exp2(x*log2(x))
。它继承了 4.7.1 中所述的上述表达式的精度。没有说明 pow(1, x)
等于 1
.
现在,用 可能正确的 中间结果扩展上面的表达式,正确的结果应该是 +INF
,因为 log2(+INF) = +INF
和 1*+INF
仍然是 +INF
,exp2(+INF) = +INF
。
但是,该标准并没有真正定义它。它仅显式(未)定义零指数。
很接近,但从规范中复制了一个错误:
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
我注意到我的一个计算着色器出现了一些奇怪的行为,它们 return 出乎意料。
在仔细调查时,我发现 pow
是罪魁祸首:
pow(1, inf) == NaN
从 C/C++ 的角度来看,我希望 pow(1, inf) == 1
:
pow(+1, exponent) returns 1 for any exponent, even when exponent is NaN
是否为此输入定义了 GLSL 的 pow
?
我只在规范中找到 base < 0
和 base == 0 && exponent <= 0
的常见例外情况。
虽然计算着色器有点暗示您使用 GPU 和 GLSL 版本(> 1.30)来执行符合 IEEE 的浮点数学运算,但这不是您可以想当然的事情,不幸的是。所以...这里是龙。
你从C++的角度引用C++参考的推理是合理和正确的,但是它省略了一个小而重要的句子:"If the implementation supports IEEE floating-point arithmetic (IEC 60559),"。这个小句子强调它既不是 C++ 要求(只是巧合,因为 IEEE 754 要求它,而且 通常 C++ 实现符合 IEEE),也不是严格保证(它是完全允许 C++ 实现 而不是 实现 IEEE 754)。
此外,GLSL 不是 C++。对于算术,这可能会让人感到惊讶,因为虽然它显然不是同一种语言,但人们可以期望数学仍然有效,不是吗?
嗯,不。 pow(x, y)
在 GLSL 中被定义为(虽然在线手册页所基于的 8.2 没有明确说明)为 exp2(x*log2(x))
。它继承了 4.7.1 中所述的上述表达式的精度。没有说明 pow(1, x)
等于 1
.
现在,用 可能正确的 中间结果扩展上面的表达式,正确的结果应该是 +INF
,因为 log2(+INF) = +INF
和 1*+INF
仍然是 +INF
,exp2(+INF) = +INF
。
但是,该标准并没有真正定义它。它仅显式(未)定义零指数。
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