【发布时间】:2017-12-14 13:06:35
【问题描述】:
我的数据库中有三个数字,想在 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
使用RetDbl(rs.value("NumA")) = 0.33、RetDbl(rs.value("NumB") = 0.5 和RetDbl(rs.value("NumC")) = 0.00083
这总是返回 false
我也试过了:
在直接字段 (STRG + G) 中:?cdbl(0.33) + cdbl(0.50) = cdbl(0.83) 返回 false。当我省略最后一部分时,它返回0.83
如何比较这些数字?
【问题讨论】:
-
浮点数不是精确值。因此,将它们与精确值进行比较可能会失败(如您所见)。最好检查
|a - b| < epsilon是否有一些适当的epsilon -
我想我应该用这个。但到目前为止,它已经工作了几天。即使我输入
?0.33 + 0.50 = 0.83i 只会得到错误。而且我从来没有告诉程序这些是双打。 -
@Ronald 是正确的。 0.33 + 0.5 = 0.8300000000000001。您还可以尝试舍入或截断以仅比较浮点数的重要部分。请参阅this website,了解有关浮点数在计算机程序中的行为方式的大量信息。
-
@Ronald 请注意,如果您要创建一个函数来进行比较,建议使用相对 epsilon
-
@ErikvonAsmuth 是的,我知道。这就是我写“一些适当的ε”的原因。通常你有 8-12 位的精度(但这可能会更糟,取决于历史;如果它是数值不稳定算法的结果,你可以得到任何结果),因此与
10^-8 * a比较可能是一个合适的值。由于我对号码的“历史”一无所知,所以我对发布号码有点谨慎。