gpt4 book ai didi

c++ - 计算平均值时的舍入误差

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:59:33 30 4
gpt4 key购买 nike

我在 C++ 中遇到舍入错误的问题。如果我必须计算两个 float ab 的平均值,那么为什么做 a+0.5*(b-a)(a+b)/2?我不明白为什么这两种计算方式应该有任何区别。

最佳答案

[免责声明:此答案假定 IEEE 754格式和语义。具体来说,我们假设 float 是 IEEE 754 binary32 格式,我们使用默认的 round-ties-to-even 舍入模式,并且中间表达式不是以扩展精度计算的 - 例如,因为FLT_EVAL_METHOD0。]

以下是首选 a + 0.5 * (b-a) 的一个可能原因:if ab 是非常大且符号相同,则表达式 0.5 * (a + b) 中的中间量 a + b 可能溢出,给出无限结果或 float -点异常。相反,a + 0.5 * (b - a) 在那种情况下不会溢出。

然而,这个小优势应该与以下各项进行权衡:

  • a + 0.5 * (b - a) 需要三个浮点运算; 0.5 * (a + b) 只需要两个。
  • a + b 溢出的情况下,0.5 * (a + b) 总是提供正确的四舍五入的答案:也就是说,在给定目标类型的可表示性约束的情况下,它给出了对实际均值的最佳近似值。 (这不是完全显而易见,但不难证明:a + b 的幅度大于最小法线的两倍,在这种情况下,总和被正确舍入并且与 0.5 的乘法是精确的,或者 a + b 本身是精确计算的,然后与 0.5 的乘法是正确舍入的。无论哪种方式,在两个算术运算中的大多数都可能引入错误。)但是 a + 0.5 * (b - a)总是给出正确舍入的平均值,事实上可能有数百万 ulp 的错误。考虑 a = -1.0b = 1.0 + 2^-23 的情况。然后 a + 0.5 * (b - a) 给出 0.0。正确的平均值是 2^-24
  • 表达式 a + 0.5 * (b - a) 也可以 溢出,如果 ab非常大,带有相反的 符号而不是相同的符号。在那种情况下,0.5 * (a + b) 不会溢出。
  • a + 0.5 * (b - a)0.5 * (a + b) 可读性差(非常轻微);读者需要花更多时间思考才能弄清楚它在做什么。

鉴于上述情况,很难支持一般性建议,即应优先使用 a + 0.5 * (b - a) 而不是 0.5 * (a + b).

关于c++ - 计算平均值时的舍入误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48740200/

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