【问题标题】:How to make doubles work properly? c#如何使双打正常工作? C#
【发布时间】:2012-05-28 10:00:08
【问题描述】:

代码如下:

    static void Main(string[] args)
    { 
        int xd2 = 5;

        for (double xd = (double)xd2; xd <= 6; xd += 0.01)
        {
            Console.WriteLine(xd);
        }

    }

这是输出:

我想继续加 0.01(正如你在屏幕上看到的,有时它恰好加了 0.99999) 谢谢

【问题讨论】:

  • Double 在 C# 中可以正常工作;-)
  • 你为什么要把 int 转换成 double 呢?
  • 尝试使用不同的步骤,例如,0.125。一旦你明白了原因,你就会学到一些很有启发性的东西:)
  • Jon Skeet 有一系列关于这个主题的文章:Binary Floating Point, Decimal Floating Point

标签: c# double


【解决方案1】:

如果您想保持这种准确性,请使用decimal

浮点类型无法准确表示某些值。我建议阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic 以获得全面的解释。

decimal xd2 = 5m;

for (decimal xd = xd2; xd <= 6m; xd += 0.01m)
{
    Console.WriteLine(xd);
}

【讨论】:

  • 值得注意的是,decimal 从根本上说并不比double 更“精确”(除了它拥有的更多位数)。它只是以 10 为基数存储,因此以熟悉的小数点表示法表示的数字(如您的示例)可以精确表示,而在 base-2 floatdouble 类型中,它们不能。 floatdouble 可以精确存储以二进制点表示法表示的数字;这只是不是很有用,因为没有人使用这种表示法。
【解决方案2】:

没有。这就是双打的工作方式....尝试使用小数代替

 int xd2 = 5;

 for (decimal xd = (decimal)xd2; xd <= 6; xd += 0.01M)
 {
     Console.WriteLine(xd);
 }

如果你想坚持双打,但只关心两位小数,请使用...

int xd2 = 5;

for (double xd = (double)xd2; xd <= 6; xd += 0.01)
{
   Console.WriteLine(Math.Round(xd,2));
}

【讨论】:

    【解决方案3】:

    这是因为 double 是浮点型的,而且这种算法并不精确。 您可以改用小数,如下所示:

     static void Main(string[] args)
        {
            int xd2 = 5;
    
            for (decimal xd = (decimal)xd2; xd <= 6; xd += 0.01M)
            {
                Console.WriteLine(xd);
            }
            Console.ReadLine();
        }
    

    也请看这篇文章:Double precision problems on .NET

    【讨论】:

    • decimal 也是浮点类型;只是以 10 为基数,而不是以 2 为基数。
    【解决方案4】:

    如果可能,您应该始终使用绝对而不是迭代计算来消除这些类型的舍入错误:

    public static void Main(string[] args)
    {
        int xd2 = 5;
    
        for (int i = 0; i < 100; ++i) {
            Console.WriteLine(xd2 + i * 0.01);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-09-24
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 2021-10-25
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 2018-07-06
      相关资源
      最近更新 更多