假设我想将一个数字分为多个。
a /= x;
b /= x;
c /= x;
...
由于乘法更快,因此诱惑是这样做的
tmp = 1.0f / x;
a *= tmp;
b *= tmp;
c *= tmp;
...
1)是否保证产生相同的答案?我怀疑不是,但有些确认会很好。
2)如果
x
过大或过小,我认为这可能会导致准确性显着下降。有没有一个公式可以告诉我要牺牲多少精度?3)也许没有方便的公式,但是我们至少可以说出何时出现数字不稳定性问题的经验法则吗?是与操作数的大小有关,还是与操作数的大小之间的差异有关?
最佳答案
1)不,不保证产生相同的答案。即使使用IEEE,通过使用a/x
或a*(1/x)
,细微的舍入效果也可能导致ULP不同于1或2。
2)如果x
极小(与子法线的情况相比,比DBL_MIN
(最小归一化的正浮点数)小一点),则1/x
是INF
,但会完全失去精度。 x
非常大时,如FP模型不支持次法线时,也会导致精度的显着降低。
通过针对最大数量的|x|
和最小的非零<= 1/DBL_MIN
测试>= 1/DBL_MAX
,代码可以确定何时开始显着降低准确性。公式可能取决于所使用的FP模型和x
的指数以及模型的限制。在binary64的范围内,x
和Emin
(或Emax
)的二进制指数之差将是丢失比特的一阶估计。
3)在上面讨论的范围内会出现明显的数值不稳定性。
关于c - 除以分母时,数值不稳定的风险是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28279490/