C 预划分分母时,数值不稳定的风险是什么?

C 预划分分母时,数值不稳定的风险是什么?,c,floating-point,numeric,ieee-754,C,Floating Point,Numeric,Ieee 754,假设我想把一个数字分成许多 a /= x; b /= x; c /= x; ... 因为乘法运算速度更快,所以我们很想这样做 tmp = 1.0f / x; a *= tmp; b *= tmp; c *= tmp; ... 1) 这能保证得到相同的答案吗?我想不会,不过确认一下就好了 2) 如果x非常大或非常小,我预计这可能会导致严重的精度损失。有没有一个公式可以告诉我我会牺牲多少准确性 3) 也许没有方便的公式,但我们能至少说明一个经验法则,说明什么时候数值不稳定性会成为一个问题吗?这是

假设我想把一个数字分成许多

a /= x;
b /= x;
c /= x;
...
因为乘法运算速度更快,所以我们很想这样做

tmp = 1.0f / x;
a *= tmp;
b *= tmp;
c *= tmp;
...
1) 这能保证得到相同的答案吗?我想不会,不过确认一下就好了

2) 如果
x
非常大或非常小,我预计这可能会导致严重的精度损失。有没有一个公式可以告诉我我会牺牲多少准确性

3) 也许没有方便的公式,但我们能至少说明一个经验法则,说明什么时候数值不稳定性会成为一个问题吗?这是与操作数的大小有关,还是可能与操作数大小之间的差异有关?

我的50美分:

1) 不,第3节进一步解释

2) 我不知道任何公式,所以我跳过这一个

3) 我所知道的经验法则是,尽量只在数量级相近的操作数之间执行运算

实际样本:

您要将数字63.000.000除以1.000.000

使用第一种方法,最终将63*10^6除以1*10^6,它们的震级非常接近

但是,如果您使用第二种方法,那么

temp = 1.0f / x;
将产生10^(-6)

现在,乘以63*10^6*10^(-6)将导致严重的精度损失,因为两者之间的震级差异巨大。CPU将尝试使用10^6数字的指数+分数表示来表示10^(-6)数字

一个可行的替代方案是使用temp

temp = 1 / 1.000;
然后

a = a * temp * temp ;

因为震级将更接近,所以精度损失的可能性更小。

当您使用ieee-754数字时,我认为您的方法是完全可以接受的。在ieee-754中,x大约是

mantisa*2指数

其中mantisa是介于1/2和1之间的数字

因此,只要你只进行乘法和除法运算,你当然会有精度损失,但这种损失与
x
(*)的大小无关,并且只与所使用的浮点类型的精度有关(单精度,四精度的双精度,这意味着
浮点
双精度
长双精度
,具体取决于编译器和体系结构)

(*)只有在不存在底流溢出的情况下,这才是正确的,单精度为1038左右,双精度为10300左右


简历:维基百科上的页面和链接如下:

1)-产生相同的结果?没有保证。对可变性有太多的影响,从486 DX数学协处理器的升级设计(还记得吗?)到编译器实现,再到浮点存储在硬件内存中的方式。(

2)-配方奶粉?我不知道有一个。你说的重大错误是什么意思?在任何情况下,您都可以通过以下方式建立精度预期:

  • 理解浮点数(链接2)
  • 所使用的变量类型(
    float
    double
    long double
    )。(
  • 你在建筑什么样的建筑 32位,还是64位,其他
关于浮点错误有很多讨论

3)没有真正的经验法则(如果经验法则的意思是易于记忆、易于应用、易于理解),但是,这里是在回答有关浮点错误的问题时所做的。

1)不,不能保证得到相同的答案。即使使用IEEE,通过使用
a/x
a*(1/x)
,细微的舍入效应也可能导致1或2的不同

2) 如果
x
非常小(即比次正态情况下的
DBL_MIN
(最小规范化正浮点数)小一点),
1/x
INF
,精度完全损失。如果
x
非常大,则可能会出现严重的精度损失,如FP模型不支持次正态分布。
通过对最大有限数
=1/DBL|u MAX
进行测试
|x |
,代码可以确定何时开始出现严重的精度损失。公式可能取决于所使用的FP模型和
x
的指数以及模型的限制。在此范围内,
x
Emin
(或
Emax
)的二进制指数之差将是位丢失的一阶估计值


3) 在上面讨论的范围内会出现显著的数值不稳定性。

否,这不会导致精度损失。如果操作数都不是非规范的,则有效位总是非常接近。指数很容易调整。只有大小差别很大的加减法通常是有问题的。@Rudy Velthius你说得对。我将修改我的答案并使操作数为denromal。我想用10的幂来强调精度损失,这让我展示了一种情况,事情实际上很容易处理。不同指数的乘法和除法不会造成比平常更多的损失。然而,指数差大的加法和减法会造成很大的损失或精度。考虑有限<代码>双< /代码>数字,让我们假设<代码> x> 0 < /代码>。通常,最大有限值
DBL_MAX
DBL_MIN
(最小规范化正浮点数)是彼此适当的倒数。由于它们很容易不是彼此的精确数学逆,因此其中一个具有可表示的逆,而另一个则不具有。这就是问题的开始。大多数FP也使用次法线,因此num的范围