首页 > 解决方案 > 将值 -pi 约束为 pi 以获得精度增益

问题描述

将任何值从 -pi 限制为 pi 的最佳方法是什么?

我目前有:

if (fAngle > XM_PI) {
  fAngle = fAngle - XM_2PI;
}
else if (fAngle < -XM_PI) {
  fAngle = fAngle - -XM_2PI;
}

但是,我担心那些 if 应该是 while

作为参考,在Exploit Symmetrical Functions部分下:

https://developer.arm.com/solutions/graphics-and-gaming/developer-guides/learn-the-basics/understanding-numerical-precision/mitigating-loss-of-precision

额外的精度!

标签: c++cmathprecisiontrigonometry

解决方案


加法或减法XM_2PI无法恢复已丢失的任何准确性。事实上,它增加了噪声,通常会损失更多的准确性,因为XM_2PI它必然只是 2π 的近似值。它本身有一些误差,因此添加或减去它会增加或减去近似值中的误差。

它可以做的是通过确保未来的结果保持较低的幅度来防止您失去更多的准确性,从而保持在浮点格式比数字超过 4、8、16 或其他点时具有更高精度的区域其中指数变化,绝对精度变差。

如果你已经在 [−π, π] 之外有一些值并且想要它的正弦或余弦,你应该直接使用orx得到最好的结果。and的良好实现将使用 2π 的高精度值来减少参数,因此您将获得比使用or更好的结果(除非偶然地,这些错误中的各种错误碰巧取消了)。sin(x)cos(x)sincossin(x-XM_PI)cos(x-XM_PI)

因此,三角函数的任务不是减少已有的值,而是设计算法以防止值增长。添加或减去 2π 是一种合理的方法。但是,当你这样做时,添加或减去 2π 的扩展精度版本,而不仅仅是XM_2PI. 您可以通过将 2π 表示为XM_2PI(应该是最接近 2π 的浮点数表示的值)加上一些残差来做到这一点rr应该是最接近 2π−<code>XM_2PI 的浮点数表示的值。您可以使用 GMP 或 Maple 等扩展精度软件进行计算,并且很可能在网上找到它。(我手边没有,或者我会把它贴在这里;欢迎其他人编辑它。)然后你可以用fAngle = fAngle - XM_2PI - r;或更新你的角度fAngle = fAngle + XM_2PI + r;

一个例外情况是,如果您以某个可以精确表示或减少的单位测量角度,例如以度为单位(只要度数本身没有错误地表示,您可以减少 360 度而没有错误)或以时间(例如以一天为周期的某些功能的秒数或其他合理的秒数,因此您可以再次减少而不会出错)。在这种情况下,您可以让角度增长,只要您可以准确地表示它,并且您可以在将其转换为弧度之前以周期为模减少它。


推荐阅读