1

我在浮点运算中确实存在取消问题。我知道问题出在哪里,但我想不出一个有效的解决方案。

这是我的问题:我有一个 3D 粒子模拟,所以每个粒子都有 3 个坐标(x,y,z)。整个域被分成子单元。在某一时刻,我计算了粒子在某个时间步长所在的子单元格的 ID。这是一个简单的公式:

   int cellOffset_y = (pos[1] - y_min) / cellWidth_y;

pos[1] 是粒子的 x 坐标,y_min 是域的开始,cellWidth 是单元格的宽度。

这是我的问题:我有一个测试用例,在这种情况下粒子的坐标应该是 0。由于浮点不准确,它大约是。-3e-18。当我使用这个公式时,-3e-18 由于取消而下降。现在最大的问题是,由于粒子位置为负,并且边界正好在 0,我得到的 cellID 与粒子实际所在的 cellID 不同。

那么有人知道如何解决这个问题吗?我希望它说清楚

4

1 回答 1

2

基本上有两个选择(好吧,三个,如果你把“忍受这个问题”算作一个有效的选择!):

  1. 稍微移动网格中的边界,以允许一定程度的上游不准确。所以计算会变成(pos - y_min + k) / width,对于一些小的值k

    当然,这并不能处理在另一个方向上发生的错误(即数字稍微太大);事实上,这使情况变得更糟。但是没有通用的方法来解决这个问题;您的代码无法“知道” -3e-18 是正确的还是稍微错误的!

  2. 修复上游计算。

于 2013-03-06T20:01:11.013 回答