c# - 比较从 double 转换的小数是否安全

标签 c# .net floating-point

众所周知,使用 == 运算符比较 double 值是不安全的。在此示例中,它返回 false:

double d1 = 0.11;
double d2 = 0.44 - 0.33;
Console.WriteLine(d1 == d2);

但是,如果我们将值转换为十进制,它会返回 true:

double d1 = 0.11;
double d2 = 0.44 - 0.33;
Console.WriteLine((decimal)d1 == (decimal)d2);

比较从 double 转换而来的小数是否总是安全的,或者在某些情况下会产生意想不到的结果?

更新: 侯赛因的例子很好,它表明它可能是错误的。但我更感兴趣的是看看是否有相反的例子,当我们期望十进制值相等而它们不相等时。更广泛地说,当我们从 double 转换为 decimal 时到底发生了什么。

最佳答案

It is commonly known that it is not safe to compare double values in .net. In this example it returns false

你误会了什么是不安全的。

假定任意十进制表示形式(即使它很短(以十进制形式书写))精确地以二进制 float 表示是不安全的。假设二进制浮点值之间的 - 产生与数学结果最接近的可表示浮点值以外的任何东西是不安全的(特别是,假设它总是不安全是不安全的产生数学结果)。

d1 == d2 是绝对安全的,(decimal)d1 == (decimal)d2 也是如此。第一个不会总是返回你看起来想要的东西,但第二个也不会,因为根据上面列出的原则,它没有理由。一旦计算出 d1d2,近似值就已经完成:

  • 表示近似,因为你似乎认为 0.11 应该是数学值 11/100,其实不是,它是最接近的可表示值;
  • 运算近似,因为 0.44 减去 0.33 的数学结果可能无法精确表示,在这种情况下,将使用最接近的可表示值。

事实上,这些近似值是复合的,并且在 C# 中添加转换为 decimal 的第三个近似值时,结果是您期望的值,这纯属巧合。如果有什么应该众所周知的话,那就是在近似值发生后修复它已经太晚了,添加另一个近似值也无济于事。请参阅本文中的第一个示例,Excel ,Microsoft 的另一款可编程产品。

关于c# - 比较从 double 转换的小数是否安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43929468/

相关文章:

c# - aspnet-core-ad-authentication 项目 HTTP 错误 502.5 - 进程失败

c# - 与 Oracle 数据库连接失败

c# - 需要上传文件,并在 pre-init 事件中使用它

.net - TurboTax 上的屏幕共享

C#:如何打开选择了多个文件的 Windows 资源管理器窗口

c# - VB.Net中的主要功能在哪里

.net - TFS 映射与颠覆

python - 标准库 - 更高精度的 float ?

c++ - 最大化精度的操作顺序

r - R 中的 for 循环与 while 循环