HLSL:强制浮点运算顺序以防止舍入错误

问题描述 投票:0回答:1

在 HLSL 中编写着色器时,有时您可能会遇到非常大的浮点数,并且对于大浮点数,它们很难保持精度。当我编写下面的代码时,我打算先减去大的但非常圆的数字,然后再添加小的小数。但是,HLSL 编译器似乎以相反的顺序执行操作,大概是为了优化。它只会产生令人无法接受的糟糕结果。

jdsatepoch is 2460432.5
jdsatepochF is .605138

float computeEpoch = (jdsatepoch-2433281.5) + jdsatepochF; 

Expected value: 27152.105569  << tiny error    (Good)
Actual value: 27151.5         << MASSIVE error (Bad)

我似乎找不到任何机制来“强制”编译器维持浮点运算的顺序,这样它就不会破坏我所有的小数精度。是否有某种机制说“请具体按此顺序执行这些操作”?

floating-point precision hlsl rounding-error
1个回答
0
投票

至少在我的情况下,在浮点变量前面加上“精确”标签似乎可以修复这种情况。我不知道情况是否总是如此,但我一路上注意到的其他一些事情:

  • 使用临时变量并稍后使用该临时变量的结果
  • #pragma skip_optimizations d3d11
    (驱动仍在优化)

precise
标签的应用似乎还取决于其他相关变量也被标记为精确。这个结果看起来相当稳健。

precise float jdsatepoch = tledat0.y;
float jdsatepochF = tledat0.z;
precise float computeEpoch = (jdsatepoch) + jdsatepochF;
precise float initialTimeMinutes = ( (jdDay - 2433281.5 - jdsatepoch) + jdFrac - jdsatepochF)*24.0 * 60.0;
© www.soinside.com 2019 - 2024. All rights reserved.