C# 双值相加不一致

C# 双值相加不一致,c#,.net,vb.net,C#,.net,Vb.net,在使用eval(…)实现开发一些工程规则值引擎时,我遇到了以下问题 Dim first As Double = 1.1 Dim second As Double = 2.2 Dim sum As Double = first + second If (sum = 3.3) Then Console.WriteLine("Matched") Else Console.WriteLine("Not Matched")

在使用eval(…)实现开发一些工程规则值引擎时,我遇到了以下问题

    Dim first As Double = 1.1
    Dim second As Double = 2.2
    Dim sum As Double = first + second
     If (sum = 3.3) Then
        Console.WriteLine("Matched")
    Else
        Console.WriteLine("Not Matched")
    End If
'上述条件返回false,因为sum的值是3.30000000000000003,而不是3.3

看起来第15位数字是往返的。有人可能会对此给出更好的解释


Math.Round(…)是唯一可用的解决方案,还是我还可以尝试其他方法?

这就是双倍数字在PC中的工作原理。 比较它们的最佳方法是使用这样的结构

if (Math.Abs(second - first) <= 1E-9)
 Console.WriteLine("Matched")

if(Math.Abs(second-first)与浮点运算的等式比较总是不准确的,因为在机器中分数值是如何表示的。您应该有某种epsilon值来进行比较。下面的一篇文章对此进行了更全面的描述:


编辑:数学。舍入将不是一个理想的选择,因为它会在某些比较中产生错误。您最好确定一个ε值,该值可用于限制比较中的错误量(基本上确定准确性级别).

A
double
使用浮点运算,这是近似值,但效率更高。如果需要与精确值进行比较,请使用
decimal
数据类型。

您不是在添加小数,而是在添加double

并不是所有的双精度运算都能在计算机中准确地表示出来,因此出现了错误。我建议阅读这篇文章作为背景(每个计算机科学家都应该知道浮点运算)

改为使用Decimal类型,它不会遇到这些问题

Dim first As Decimal = 1.1
Dim second As Decimal = 2.2
Dim sum As Decimal= first + second
 If (sum = 3.3) Then
    Console.WriteLine("Matched")
Else
    Console.WriteLine("Not Matched")
End If
在C#、Java、Python和许多其他语言中,小数/浮点数并不完美。由于它们的表示方式(使用乘法器和指数),它们通常不准确。有关更多信息,请参阅文档中的。

浮点值和数据丢失 精密度

记住一个浮点数 只能近似一个十进制数, 这就是 浮点数决定了 准确地说,这个数字接近a 十进制数。默认情况下,为双精度 值包含15个十进制数字 精度,但最大值为17 数字是在内部维护的 浮点数的精度 这有几个后果:

显示的两个浮点数 对于某个特定的精度可能相等 不平等,因为他们最不平等 有效数字是不同的

数学运算或比较运算 使用浮点数的 如果 使用十进制数是因为 浮点数可能不是 精确地逼近小数点 号码

如果 涉及浮点数。A 如果 操作转换原始文件 将浮点数转换为另一种形式, 一个逆运算可以变换 将表单转换回 浮点数,以及最终的 浮点数等于 原始浮点数 由于一个或多个原因,往返可能失败 更多的最低有效数字丢失 或在转换中更改

另外,对算法的结果进行了分析 与双精度赋值运算 各平台的值可能略有不同 因为失去了测量的精确性 双重类型。例如 分配文本双精度的结果 值在32位和中可能不同 .NET Framework的64位版本。 下面的示例说明了这一点 当文本值 -4.423306044772E-305和一个值为-4.4233060404244772E-305的变量 分配给一个双变量。 请注意 本例中的Parse(String)方法 不会遭受精度损失


这是浮点算术的一个众所周知的问题。有关详细信息,请查看二进制编码

如果适合您的需要,请使用“decimal”类型

但一般来说,永远不要将浮点值与带等号的常量浮点值进行比较

否则,请与您要比较的位置数进行比较(例如,假设它是4,则您会去(如果sum>3.2999,sum<3.3001)

可能的重复