gpt4 book ai didi

c++ - 平方差的数值精度

转载 作者:可可西里 更新时间:2023-11-01 17:41:26 26 4
gpt4 key购买 nike

在我的代码中,我经常计算类似下面的部分(为简单起见,此处为 C 代码):

float cos_theta = /* some simple operations; no cosf call! */;
float sin_theta = sqrtf(1.0f - cos_theta * cos_theta); // Option 1

对于此示例,请忽略平方根的自变量由于不精确而可能为负数。我通过额外的 fdimf 调用修复了这个问题。但是,我想知道以下是否更准确:

float sin_theta = sqrtf((1.0f + cos_theta) * (1.0f - cos_theta)); // Option 2

cos_theta 介于 -1+1 之间,因此对于每个选择,在某些情况下我会减去相似的数字,从而降低精度, 正确的? 什么是最精确的,为什么?

最佳答案

使用 float 最精确的方法可能是使用单个 x87 指令计算 sin 和 cos, fsincos

但是,如果您需要手动进行计算,最好将具有相似量级的参数分组。这意味着第二个选项更精确,尤其是当 cos_theta 接近 0 时,精度最重要。

作为文章 What Every Computer Scientist Should Know About Floating-Point Arithmetic备注:

The expression x2 - y2 is another formula that exhibits catastrophic cancellation. It is more accurate to evaluate it as (x - y)(x + y).

编辑:它比这更复杂。虽然上述内容通常是正确的,但当 x 和 y 的大小非常不同时,(x - y)(x + y) 稍微不太准确,正如声明的脚注所解释的:

In this case, (x - y)(x + y) has three rounding errors, but x2 - y2 has only two since the rounding error committed when computing the smaller of x2 and y2 does not affect the final subtraction.

换句话说,取 x - y、x + y 和乘积 (x - y)(x + y) 都会引入舍入误差(3 步舍入误差)。 x2、y2 和减法 x2 - y2 也都引入了舍入误差,但是通过对相对较小的数(x 和 y 中的较小者)进行平方得到的舍入误差可以忽略不计,实际上只有两步舍入误差,使平方差更加精确。

所以选项 1 实际上会更精确。 dev.brutus 的 Java 测试证实了这一点。

关于c++ - 平方差的数值精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18212862/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com