2

我正在尝试遍历 X 和 Y 的所有组合。我将值增加 0.01,这是一个双精度值,但它实际上从未达到 0。

for (double x = -50; x < 50; x += 0.01)
{
     for (double y = -50; y <50; y += 0.01)
     {
          //Some code
     }
}

知道为什么会这样吗?我假设这与“双重”有关,如果是这样,我可以用什么作为替代方案?

更新:我将其更改为十进制并将所有十进制数字更改为末尾有一个“m”。现在一切正常,我爱你们:D

代码现在读取 -

for (decimal x = -50; x < 50; x += 0.01m)
{
      for (decimal y = -50; y < 50; y += 0.01m)
      {
            // Some code
      }
}
4

7 回答 7

2

我怀疑您正在测试零,如下所示:

if (x == 0.0) {
    // it is zero.
}

由于浮点舍入错误,这可能会失败。

浮点数的属性之一是它们没有对许多十进制数的精确表示。在这种情况下,您会发现 0.01 最接近的表示是“关闭”了一个很小的量。所以当你0.01加到-50.0五千次时,结果并不完全正确0.0

您需要测试是否x是零加/减一些小错误;例如0.00001,在这种情况下应该没问题。

更好的是,您可以通过将循环变量声明为整数然后将其除以 0.01 来给出您的值,从而避免整个舍入x问题y;例如

for (int i = -5000; i < 5000; i++) {
    double x = i / 0.01d;
    // etcetera

实际上,由于您的代码使用的是 a0.01而不是0.01d,因此我认为表示中的错误将超出应有的范围...

于 2013-02-02T14:28:42.303 回答
2

由于舍入/截断错误,不可能将值 0.01 完全存储在双精度值中。因此,将它们中的几个相加会增加错误的幅度,可能使其错过 0。相反,请尝试使用小数类型或迭代整数。

于 2013-02-02T14:31:28.437 回答
2

问题是计算机中的浮点数通常不能精确地表示十进制值,它们只能近似它们。您可以查看有关浮点数的 wiki 文章以获取更多详细信息。

如果你使用这样的东西,你的代码会更好:

for (int idxX = -5000; idxX < 5000; idxX += 1)
{
    double x = (double) idxX / 100.0;

    for (int idxY = -5000; idxY < 5000; idxY += 1)
    {
        double y = (double) idxY / 100.0;

        //Some code
    }
}

这避免了浮点数的一些问题。

于 2013-02-02T14:32:06.037 回答
0

试试这个技巧:

for (int x = -5000; x < 5000; x++)
    {
         for (int y = -5000; y <5000; y++)
         {
              System.out.println((double)x/100.0+" ~~ "+(double)y/100.0);
         }
    }

问候,

于 2013-02-02T14:32:34.067 回答
0

请改用小数。然后你会打到 0。用双精度计算会给你舍入错误

于 2013-02-02T14:32:36.600 回答
0

在大多数 C 派生语言中,doublefloat是具有以 2 为底的的数字。这意味着它与十进制数本身几乎没有关系,并且不一定总是准确地存储它们,它只是存储一个近似值。

对此的解决方案是使用以 10 为底的幂,幸运的是,C# 有一个具有此属性的类型:decimal. 替换doubledecimal,你可能很高兴。

于 2013-02-02T14:39:28.120 回答
0

这个怎么样:

if (x == (.01-.01)){}
于 2013-02-02T14:40:06.253 回答