我的数据库中有三个数字,想要在 if 语句中比较它们。
我有一个简单的 convert 函数,仅返回双精度数。
Public Function RetDbl(ByVal obj As Variant) As Double
On Error Resume Next
RetDbl = val(Replace(Nz(obj, 0), ",", "."))
End Function
声明是
If RetDbl(rs.value("NumA")) + RetDbl(rs.value("NumB")) <> (RetDbl(rs.value("NumC")) * 1000) Then
'[... do some code ...]
End If
With RetDbl(rs.value("NumA")) = 0.33
, RetDbl(rs.value("NumB") = 0.5
and RetDbl(rs.value("NumC")) = 0.00083
这总是返回 false
我也尝试过:
在直接场(STRG + G):?cdbl(0.33) + cdbl(0.50) = cdbl(0.83)
回报false
。当我省略最后一部分时它会返回0.83
我如何比较这些数字?
比较浮点数很困难。就在昨天,我才发帖这个问题
我的解决方案:
Public Function DblSafeCompare(ByVal Value1 As Variant, ByVal Value2 As Variant) As Boolean
'Compares two variants, dates and floats are compared at high accuracy
Const AccuracyLevel As Double = 0.00000001
'We accept an error of 0.000001% of the value
Const AccuracyLevelSingle As Single = 0.0001
'We accept an error of 0.0001 on singles
If VarType(Value1) <> VarType(Value2) Then Exit Function
Select Case VarType(Value1)
Case vbSingle
DblSafeCompare = Abs(Value1 - Value2) <= (AccuracyLevelSingle * Abs(Value1))
Case vbDouble
DblSafeCompare = Abs(Value1 - Value2) <= (AccuracyLevel * Abs(Value1))
Case vbDate
DblSafeCompare = Abs(CDbl(Value1) - CDbl(Value2)) <= (AccuracyLevel * Abs(CDbl(Value1)))
Case vbNull
DblSafeCompare = True
Case Else
DblSafeCompare = Value1 = Value2
End Select
End Function
请注意,AccuracyLevel (epsilon) 可以设置为较小的值,并且我对单打和双打使用相同的值,但它非常适合我的目的。
我使用的是相对 epsilon,但将其与第一个值相乘,而不是最大值,因为如果存在显着差异,则比较无论如何都会失败。
请注意,我正在使用<=
并不是<
因为其他DblSafeCompare(cdbl(0) ,cdbl(0))
会失败
请注意,此函数检查类型相等性,因此将整数与长整型、双精度型与单精度型等进行比较都会失败。然而,比较 Null 与 Null 传递。
实施它:
?DblSafeCompare(cdbl(0.33) + cdbl(0.50) ,cdbl(0.83))
?DblSafeCompare(cdbl(0.331) + cdbl(0.50) ,cdbl(0.83))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)