C# - 双操作简单

时间:2016-07-08 06:36:43

标签: c#

我写这个简单的程序只是为了表明我用双操作的一个小问题。

namespace WpfApplication3
{
   public partial class MainWindow : Window
   {
        public MainWindow()
        {
            InitializeComponent();

            double a = 110.0;
            double b = a / 100.0;
            double c = Math.Round(b, 2);
            if ((c % 0.05) == 0)
                Console.WriteLine("Good news!");
            else
                Console.WriteLine("Bad news!");
        }
   }
}

我做错了,如果运行程序,在控制台上看到“坏消息!”.... 感谢您的意见,问候

3 个答案:

答案 0 :(得分:3)

Double不准确,您不能完全使用float / double表示所有数字,这会导致意外行为。所以你需要使用十进制:

decimal a = 110.0m;
decimal b = a / 100.0m;
decimal c = Math.Round(b, 2);
if ((c % 0.05m) == 0)
    Console.WriteLine("Good news!");
else
    Console.WriteLine("Bad news!");

输出:

Good news!
  

十进制类型的精度高于任何内置类型   .NET中的二进制浮点类型,尽管它的范围较小   潜在的指数此外,许多操作产生惊人的   由于不精确的表示形式导致二进制浮点   原始操作数以十进制浮点消失,正是因为   许多操作数在源代码中专门表示为小数。   但是,这并不意味着所有操作都会突然变为现实   准确:例如,第三个仍然无法准确表示。该   潜在的问题与二元浮动的问题是一样的   点。但是,大多数情况下选择十进制类型   像金钱一样的数量,操作将是简单的并保持事物   准确。 (例如,添加指定为的税   百分比将保持数字准确,假设他们在一个   合理的范围开始。)只要知道哪些操作   可能导致不准确,而且不是。

请阅读此article了解更多信息。

答案 1 :(得分:2)

学习使用断点并调试代码,以便学习如何解决自己的问题(某些情况)。让我们来看看你的应用程序..

    double a = 110.0;
    double b = a / 100.0;
    double c = Math.Round(b, 2); // c = 1.1
    if ((c % 0.05) == 0) // 1.1 % 0.05 = 0.000000000000000027755575615628914 which is not equal to 0.. thus it is false..
        Console.WriteLine("Good news!");
    else
        Console.WriteLine("Bad news!"); // Ooooh it's false, Bad news!

更新:

但如果你换到..

    double a = 110.0;
    double b = a / 100.0;
    double c = Math.Round(b, 2); // c = 1.1
    if (Math.Round(c % 0.05) == 0) // 1.1 % 0.05 = 0.0 which is equal to 0.. thus it is true..
        Console.WriteLine("Good news!"); // Hurray!
    else
        Console.WriteLine("Bad news!");

此外,使用十进制数据类型作为其他建议将产生相同的结果。

答案 2 :(得分:1)

使用floatdouble时,由于向上舍入错误而避免使用==!=比较,请与容差进行比较,而不是:

   ...

   double tolerance = 1e-6;

   // Comparison with tolerance: difference (if any) is less than tolerance
   if (Math.Abs(c % 0.05) < tolerance)
     Console.WriteLine("Good news!");
   else
     Console.WriteLine("Bad news!");