我正在研究一种n体重力模拟器,它采用输入并以公制MKS单位产生输出。这涉及处理一些非常大的数字(如用千克表示的太阳质量,用米表示的行星轨道的半长轴,以秒表示的年的时间尺度),它们乘以一些非常小的数字(特别是引力常数,在MKS单位中是6.67384e-11,并且偶尔增加或减少非常大的数字(主要是在成对加速时),这让我担心舍入误差的影响。
我已经采取了通过 Gm 替换所有质量 m 的步骤(通过引力常数预乘),这显着减少了乘法的总数,并且使得质量数字要小得多,这似乎对效率和准确性产生了积极影响,这可以通过模拟器节能来判断。
但是,我想知道:是否值得尝试对不同的单元进行一些内部重新调整,以进一步减少浮点错误?如果是这样,我应该尝试将我的数字集中在哪个范围(对于双精度浮点数)以获得最大精度?答案 0 :(得分:1)
一般情况下,如果您希望在基于物理的渲染中获得精确结果,则不要使用浮点数或双精度数,因为它们存在大量舍入问题,从而在模拟中引入错误。
如果您需要或想要坚持浮点数/双倍,您可能应该重新调整大约零。原因是通常浮点表示具有更高的密度"在这一点附近的值,并且在最小/最大值侧往往较少。 Image example from google
我建议您将所有值更改为基于整数的数字变量。这会消除舍入错误(上溢/下溢仍然可能发生!)并将计算过程加速一个数量级,因为正常的CPU在整数运算时工作得更快。在GPU的情况下,它的基本上相同,但另一个故事都由它自己......
但在您努力进一步提高准确性之前,我强烈建议使用任意精确数字库。这可能会带来性能损失,但应该比重新调整您的值更容易,并且产生更好的结果。
答案 1 :(得分:0)
大多数数学数学家都遇到过这个问题。 首先让我提醒您,对于每次计算,您不能处理小于机器epsilon的数字(或phsycal值)。不幸的是,epsilon取决于您正在分析的数字。你可以尝试eps(a)表示MATLAB中的任何值,只要我记得eps(1.0)〜= 2.3e-16和eps(0)~1e-298。
这就是为什么在数值方法中使用非常不同的缩放数字来避免计算的原因。因为一个被另一个值忽略(小于它的epsilon),并且舍入误差是不可避免的。
但人们还做了什么?如果他们遇到这样的物理问题,在编码之前,数学家会从理论上分析问题,他们会简化使用类似比例的数字。