【发布时间】:2013-02-21 18:59:50
【问题描述】:
我在浮点运算中确实存在取消问题。我知道问题出在哪里,但我想不出一个有效的解决方案。
这是我的问题:我有一个 3D 粒子模拟,所以每个粒子都有 3 个坐标(x、y、z)。整个域被分成子单元。在某一时刻,我计算了粒子在某个时间步长所在的子单元格的 ID。这是一个简单的公式:
int cellOffset_y = (pos[1] - y_min) / cellWidth_y;
pos[1] 是粒子的 x 坐标,y_min 是域的开始,cellWidth 是单元格的宽度。
这是我的问题:我有一个测试用例,在这种情况下粒子的坐标应该是 0。由于浮点不准确,它大约是 0。 -3e-18。当我使用这个公式时,-3e-18 由于取消而下降。现在最大的问题是,由于粒子位置为负,并且边界正好在 0,我得到的 cellID 与粒子实际所在的 cellID 不同。
那么有人知道如何解决这个问题吗?希望说明清楚
【问题讨论】:
-
你不能用一个公差来比较吗? (例如 epsilon)。
-
同样在你的片段中,
cellOffset_y是一个整数,e-18 将只是 0。 -
@111111: 我想是
pos那是-3e-18... -
是的,cellOffset_y 应该是一个 int,因为它是 y 方向上单元格的 ID。 pos[1] 在我的示例中是 -3e-18,是的
-
使用近似坐标可以获得近似的单元格 ID,尤其是当粒子位于两个单元格之间的边界时。这在粒子方法中是完全正常的。我没有看到这里的问题(我自己做了很长一段时间的粒子模拟),我会责怪你的测试用例。
标签: c++ mpi numeric floating-accuracy cancellation