Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 避免由于浮点数的二进制存储而出现意外行为的最佳方法是什么?_C#_.net_Binary - Fatal编程技术网

C# 避免由于浮点数的二进制存储而出现意外行为的最佳方法是什么?

C# 避免由于浮点数的二进制存储而出现意外行为的最佳方法是什么?,c#,.net,binary,C#,.net,Binary,我最近在写一个简单的for循环,得到了一些意想不到的行为: for(double x = 0.0; x <= 1.0; x += 0.05) { Console.WriteLine(x.ToString()); } 请注意,即使继续for循环的条件似乎包含1,也不会出现1。我意识到这是因为十进制数以二进制形式存储在内存中,也就是说,1实际上不是1,而是1.0000000000000002(根据Visual Studio中的变量watch)。所以我的问题是,避免这种意外行为的最佳方

我最近在写一个简单的for循环,得到了一些意想不到的行为:

for(double x = 0.0; x <= 1.0; x += 0.05)
{
    Console.WriteLine(x.ToString());
}

请注意,即使继续for循环的条件似乎包含1,也不会出现1。我意识到这是因为十进制数以二进制形式存储在内存中,也就是说,1实际上不是1,而是1.0000000000000002(根据Visual Studio中的变量watch)。所以我的问题是,避免这种意外行为的最佳方法是什么?一种方法是使用
decimal
类型,而不是
double
,但大多数
系统。数学
函数仅对
double
s起作用,在两者之间进行转换并不简单。

不要测试double是否相等

在这里,您可以使用整数算术:

for (int i = 0; i <= 20; ++i)
{
    double x = (double)i / 20.0;
    Console.WriteLine(x);
}

for(int i=0;i始终自己管理舍入,不要让系统处理它

  for(double x = 0.0; Math.Round(x,2,MidpointRounding.AwayFromZero) <= 1.0; x += 0.05)
  {
      Console.WriteLine(x.ToString());
  }

for(double x=0.0;Math.Round(x,2,middpointrounding.AwayFromZero)您不能放大并使用int吗

 for(int ix=0; ix < 1000; ix += 50)
 {

  }
for(int-ix=0;ix<1000;ix+=50)
{
}

如果需要的话,可以除以1000。但这样可以得到精确的循环行为,这被称为浮点错误,对此已有很多研究。对于您的情况,一个解决方案是定义一个错误,例如

err = .000001

并与err为1.0的范围内进行比较。

这个答案对我来说似乎是最好的,尽管没有一个是理想的。我不喜欢为了避免浮点错误而对不同的东西进行迭代的想法。我希望有一种方法可以告诉编译器“合理地循环”例如,假设1.0000000000000002真的是1是安全的,但是代替我认为手工数学。()是代替。确切地说,当用小数进行数学运算时,你必须考虑有效数字。
err = .000001