Cᴏʀ*_*ᴏʀʏ 6 vb.net asp.net floating-point precision decimal
所以我只是想深入研究这个问题......我有一个使用频繁的网络应用程序,这是两年来第一次使用相同功能对两个双打进行相等检查失败了一位同事说他' d也一直使用多年.
我要在这里粘贴的函数的目标是将两个double值与4位精度值进行比较并返回比较结果.为了便于说明,我的价值观是:
Dim double1 As Double = 0.14625000000000002 ' The result of a calculation
Dim double2 As Double = 0.14625 ' A value that was looked up in a DB
Run Code Online (Sandbox Code Playgroud)
如果我将它们传递给这个函数:
Public Shared Function AreEqual(ByVal double1 As Double, ByVal double2 As Double) As Boolean
Return (CType(double1 * 10000, Long) = CType(double2 * 10000, Long))
End Function
Run Code Online (Sandbox Code Playgroud)
比较失败了.在乘法并转换为Long之后,比较结果为:
Return 1463 = 1462
Run Code Online (Sandbox Code Playgroud)
我在这里回答了我自己的问题,但我可以看到它double1在双精度(17位数)的精度范围内,并且演员表正常工作.
我的第一个真正的问题是:如果我将上面的行更改为以下内容,为什么它可以正常工作(返回True)?
Return (CType(CType(double1, Decimal) * 10000, Long) = _
CType(CType(double2, Decimal) * 10000, Long))
Run Code Online (Sandbox Code Playgroud)
没有Decimal更高的精度,因此铸造到龙应该仍然是1463,并且比较回归False?我想我对这个东西有一个大脑放屁......
其次,如果要更改此功能以进行比较我正在寻找更准确或更不容易出错,您会建议将其更改为更简单的东西吗?例如:
Return (Math.Abs(double1 - double2) < 0.0001)
Run Code Online (Sandbox Code Playgroud)
我会疯狂尝试类似的东西:
Return (double1.ToString("N5").Equals(double2.ToString("N5")))
Run Code Online (Sandbox Code Playgroud)
(我绝不会做上述事情,我只是对你的反应感到好奇.在我的申请中,它会非常低效.)
无论如何,如果有人能够对我在铸造Double和铸造之间看到的差异有所Decimal了解Long,那就太好了.
谢谢!
在这种情况下依赖强制转换很容易出错,正如您所发现的 - 根据强制转换时使用的规则,您可能不会得到您期望的数字。
我强烈建议您编写不带强制类型转换的比较代码。你的 Math.Abs 线非常好。
关于你的第一个问题:
我的第一个真正的问题是:如果我将上面的行更改为以下行,为什么它可以正常工作(返回 True)?
原因是从 Double 到 Decimal 的转换丢失了精度,导致比较结果为 0.1425 到 0.1425。