Question

I have trouble comparing 2 double in Excel VBA

suppose that I have the following code

Dim a as double
Dim b as double
a = 0.15
b = 0.01

After a few manipulations on b, b is now equal to 0.6

however the imprecision related to the double data type gives me headache because

if a = b then
 //this will never trigger
end if

Do you know how I can remove the trailing imprecision on the double type?

Was it helpful?

Solution

You can't compare floating point values for equality. See this article on "Comparing floating point numbers" for a discussion of how to handle the intrinsic error.

It isn't as simple as comparing to a constant error margin unless you know for sure what the absolute range of the floats is beforehand.

OTHER TIPS

if you are going to do this....

Dim a as double  
 Dim b as double  
 a = 0.15  
 b = 0.01

you need to add the round function in your IF statement like this...

  If Round(a,2) = Round(b,2) Then   
     //code inside block will now trigger.
  End If  

See also here for additional Microsoft reference.

It is never wise to compare doubles on equality.

Some decimal values map to several floating point representations. So one 0.6 is not always equal to the other 0.6.

If we subtract one from the other, we probably get something like 0.00000000051.

We can now define equality as having a difference smaller that a certain error margin.

Here is a simple function I wrote:

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

Call it with:

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)

As has been pointed out, many decimal numbers cannot be represented precisely as traditional floating-point types. Depending on the nature of your problem space, you may be better off using the Decimal VBA type which can represent decimal numbers (base 10) with perfect precision up to a certain decimal point. This is often done for representing money for example where 2-digit decimal precision is often desired.

Dim a as Decimal
Dim b as Decimal
a = 0.15
b = 0.01

The Currency data type may be a good alternative. It handles relatively large numbers with fixed four digit precision.

Work-a-round?? Not sure if this will answer all scenarios, but I ran into a problem comparing rounded double values in VBA. When I compared to numbers that appeared to be identical after rounding, VBA would trigger false in an if-then compare statement. My fix was to run two conversions, first double to string, then string to double, and then do the compare.

Simulated Example I did not record the exact numbers that caused the error mentioned in this post, and the amounts in my example do not trigger the problem currently and are intended to represent the type of issue.

 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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top