我正在尝试迭代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
}
}
答案 0 :(得分:2)
我怀疑你正在测试这样的零:
if (x == 0.0) {
// it is zero.
}
由于浮点舍入错误,可能会失败。
浮点数的一个属性是它们没有很多十进制数的精确表示。在这种情况下,您会发现0.01的最接近的表示是一个很小的“关闭”。因此,当您将0.01
添加到-50.0
五千次时,结果并不完全是0.0
。
您需要测试x
是否为零加/减小错误;例如在这种情况下,0.00001
应该没问题。
更好的是,你可以通过将循环变量声明为整数然后将其除以0.01来得到x
和y
值,从而避免整个舍入问题; e.g。
for (int i = -5000; i < 5000; i++) {
double x = i / 0.01d;
// etcetera
事实上,由于您的代码使用的是0.01
而不是0.01d
,因此我认为代表中的错误将超过它应该是......
答案 1 :(得分:2)
由于舍入/截断错误,无法将值0.01精确地存储在double中。因此,将它们中的几个一起添加会增加错误的大小,可能会使它错过0.相反,请尝试使用十进制类型或迭代整数。
答案 2 :(得分:2)
问题是计算机中的浮点数通常不能精确地表示十进制值,它们只是近似它们。您可以查看有关floating point numbers的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
}
}
这可以避免浮点数的一些问题。
答案 3 :(得分: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);
}
}
此致
答案 4 :(得分:0)
使用小数代替。然后你会点击0.用double计算会给你舍入错误
答案 5 :(得分:0)
在大多数C语言中,double
和float
是基数为2 power的数字。这意味着它与十进制数本身的关系非常小,并且不一定总是精确地存储它们,它只是存储近似值。
解决这个问题的方法是使用基数为10的幂,幸运的是,C#有一个具有此属性的类型:decimal
。将double
替换为decimal
,您可能会很高兴。
答案 6 :(得分:0)
这个怎么样:
if (x == (.01-.01)){}