【问题标题】:How iterate through every possible combination of X and Y如何遍历 X 和 Y 的所有可能组合
【发布时间】:2013-01-17 17:49:39
【问题描述】:

我正在尝试遍历 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
     }
}

知道为什么会这样吗?我假设它与'double'有关,如果是这样,我可以使用什么作为替代方案?

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

现在的代码是 -

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

【问题讨论】:

  • 使用十进制而不是双精度

标签: c# java for-loop iterator


【解决方案1】:

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

【讨论】:

  • 谢谢,我试试看。
【解决方案2】:

问题是计算机中的浮点数通常不能精确地表示十进制值,它们只能近似它们。您可以查看关于floating point numbers 的维基文章了解更多详情。

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

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
    }
}

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

【讨论】:

    【解决方案3】:

    我怀疑你正在测试这样的零:

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

    这很可能由于浮点舍入错误而失败。

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

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

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

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

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

    【讨论】:

      【解决方案4】:

      试试这个技巧:

      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);
               }
          }
      

      问候,

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

          解决方案是使用以 10 为底的幂,幸运的是,C# 有一个具有此属性的类型:decimal。将double 替换为decimal,您可能就可以开始使用了。

          【讨论】:

            【解决方案7】:

            这个怎么样:

            if (x == (.01-.01)){}
            

            【讨论】:

            • 想解释一下吗?另外,请注意括号。他们不匹配。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-08-15
            • 1970-01-01
            • 2014-07-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多