题
我无法在Excel VBA中比较2个双倍
假设我有以下代码
Dim a as double
Dim b as double
a = 0.15
b = 0.01
在对b进行一些操作之后,b现在等于0.6
然而,与双数据类型相关的不精确让我感到头痛,因为
if a = b then
//this will never trigger
end if
你知道如何删除双重类型的尾随不精确吗?
解决方案
您无法比较浮点值是否相等。请参阅此文章“比较浮点数字"讨论如何处理内在错误。
除非你事先知道浮点数的绝对范围是什么,否则它并不像比较恒定的误差范围那么简单。
其他提示
如果你打算这样做......
Dim a as double
Dim b as double
a = 0.15
b = 0.01
你需要在你的IF语句中添加圆函数,就像这样......
If Round(a,2) = Round(b,2) Then
//code inside block will now trigger.
End If
另请参阅此处以获取其他Microsoft参考资料。
比较平等的双打是不明智的。
某些十进制值映射到多个浮点表示。因此,一个0.6并不总是等于另一个0.6。
如果我们从另一个中减去一个,我们可能得到类似于0.00000000051的东西。
我们现在可以将等式定义为具有小于某个误差范围的差异。
这是我写的一个简单的函数:
Function dblCheckTheSame(number1 As Double, number2 As Double, Optional Digits As Integer = 12) As Boolean
If (number1 - number2) ^ 2 < (10 ^ -Digits) ^ 2 Then
dblCheckTheSame = True
Else
dblCheckTheSame = False
End If
End Function
用以下方式调用:
MsgBox dblCheckTheSame(1.2345, 1.23456789)
MsgBox dblCheckTheSame(1.2345, 1.23456789, 4)
MsgBox dblCheckTheSame(1.2345678900001, 1.2345678900002)
MsgBox dblCheckTheSame(1.2345678900001, 1.2345678900002, 14)
正如已经指出的那样,许多十进制数不能精确地表示为传统的浮点类型。根据问题空间的性质,最好使用十进制VBA类型,它可以表示十进制数字(基数为10),具有完美的精度,直到某个小数点。这通常用于代表货币,例如通常需要2位十进制精度。
Dim a as Decimal
Dim b as Decimal
a = 0.15
b = 0.01
货币数据类型可能是一个不错的选择。它处理相对较大的数字,具有固定的四位精度。
工作-A-轮?? 不确定这是否会回答所有情况,但我遇到了比较VBA中的舍入双值的问题。当我将四舍五入后看起来相同的数字进行比较时,VBA会在if-then比较语句中触发false。 我的修复是运行两次转换,首先是double to string,然后是string to double,然后进行比较。
模拟示例 我没有记录导致本文中提到的错误的确切数字,并且我的示例中的金额目前没有触发问题,并且旨在表示问题的类型。
Sub Test_Rounded_Numbers()
Dim Num1 As Double
Dim Num2 As Double
Let Num1 = 123.123456789
Let Num2 = 123.123467891
Let Num1 = Round(Num1, 4) '123.1235
Let Num2 = Round(Num2, 4) '123.1235
If Num1 = Num2 Then
MsgBox "Correct Match, " & Num1 & " does equal " & Num2
Else
MsgBox "Inccorrect Match, " & Num1 & " does not equal " & Num2
End If
'Here it would say that "Inccorrect Match, 123.1235 does not equal 123.1235."
End Sub
Sub Fixed_Double_Value_Type_Compare_Issue()
Dim Num1 As Double
Dim Num2 As Double
Let Num1 = 123.123456789
Let Num2 = 123.123467891
Let Num1 = Round(Num1, 4) '123.1235
Let Num2 = Round(Num2, 4) '123.1235
'Add CDbl(CStr(Double_Value))
'By doing this step the numbers
'would trigger if they matched
'100% of the time
If CDbl(CStr(Num1)) = CDbl(CStr(Num2)) Then
MsgBox "Correct Match"
Else
MsgBox "Inccorrect Match"
End If
'Now it says Here it would say that "Correct Match, 123.1235 does equal 123.1235."
End Sub