我写这个简单的程序只是为了表明我用双操作的一个小问题。
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!");
}
}
}
我做错了,如果运行程序,在控制台上看到“坏消息!”.... 感谢您的意见,问候
答案 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)
使用float
和double
时,由于向上舍入错误而避免使用==
和!=
比较,请与容差进行比较,而不是:
...
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!");