【发布时间】:2014-05-20 00:35:52
【问题描述】:
在查找两点之间的积分点数时出现奇怪的精确行为:
我正在为此编写一个算法,如下所示(伪)。
给定 x1,y1 和 x2,y2
我计算了 double m 其中 m 是线段的梯度,给出为 (double)(y2-y1)/(x2-x1) 然后我计算了 double c 其中 c 是 y1 - (m*x1) 给出的 y 截距
那么 对于 i = Min(x1,x2) i
最后,返回结果-1
该代码适用于某些测试用例,但在其他测试用例上失败,例如当两个端点相互垂直时,我必须处理 m 的无穷大和 c 的 NaN 案例。但是,一个特殊情况引起了我的注意,分别为 x1,y1 和 x2,y2 的测试用例 43,38,17,6。
运行代码 j 从 6 开始,i 从 17 开始,所以这个点肯定在线段上,即使我不应该计算它,因为它是一个端点。奇怪的是这个值 i, j != (m*i)+c = 5.9999999999... 而不是 6。这怎么可能?我在哪里失去了精确度?更重要的是我怎么会失去精度?
代码:
int cnt = 0;
double i, j;
double m = (double)(y2 - y1) / (x2 - x1);
double c = y1 - (m * x1);
for (i = Math.Min(x1, x2); i <= Math.Max(x1, x2); i++)
{
for (j = Math.Min(y1, y2); j <= Math.Max(y1, y2); j++)
{
if (j == (m * i) + c||double.IsInfinity(m) && double.IsNaN(c))
cnt++;
}
}
return cnt - 2;
所以我将所有变量都更改为十进制,但不幸的是,我仍然得到失败的测试用例。但我想我已经把范围缩小到这里了:decimal m = (decimal)(y2 - y1) / (x2 - x1);
【问题讨论】:
-
这里不再描述你的代码,而是展示它。在没有看到一行代码的情况下帮助您解决这样的问题是非常困难的。
-
您使用的是
doubles,但如果您关心计算过程中的精度,您可能应该使用decimals(又名Money)。
标签: c# algorithm coordinate-systems