Consulting

Results 1 to 6 of 6

Thread: Compare two doubles

  1. #1
    VBAX Regular
    Joined
    Nov 2008
    Posts
    44
    Location

    Compare two doubles

    Hi, all.

    I was reading that a "safe" way to test equality of two double-type variables is to compute the absolute value of their difference and then compare that to some predetermined acceptable error margin. So, if the absolute difference is less than 0.0000001, then they are considered equal (for example).

    I was wondering if there is a reason why you couldn't just round the two variables, say to 6 decimals (or whatever number of decimals suits your needs), and then compare them directly:

    Double var1 = 10.900000001
    Double var2 = 10.900000000

    If Round(var1, 6) = Round(var2, 6) Then 'They're equal.

    Would this work?


    Thanks,

    Duluter

  2. #2
    VBAX Regular
    Joined
    Oct 2009
    Location
    Fremont, CA
    Posts
    72
    Location

    Have you tried it?

    YES.

    PS: A little experimenting goes a long way

  3. #3
    VBAX Regular
    Joined
    Nov 2008
    Posts
    44
    Location
    Thank you for the reply.

    I did try it, and it did work, but I thought that experimenting with some random numbers is a poor way to validate if it works or not--it was conceivable to me that it could work for some values and not for others because my knowledge of how these things work "behind the scenes" is not too good. It seemed to me that round-and-compare was easier than take-absolute-values-and-compare-to-predetermined-error-margin and since the recommendations I saw were for the latter, I thought I might be missing something.

  4. #4
    VBAX Contributor
    Joined
    Dec 2009
    Location
    Sevastopol
    Posts
    150
    Location
    NO!

    What if the compared are 1000000000000.01 and 1000000000000.02, but you trust to only 12 significant digits?

    I would suggest using such function:
    
    Function IsEqual(v1#, v2#, Optional Digits% = 12) As Boolean
      Dim v, i%
      v = Fix(v1)
      i = Digits - Len(v) + IIf(v = 0, 1, 0)
      If i < 0 Then
        IsEqual = Round(v1 / 10 ^ -i, 0) = Round(v2 / 10 ^ -i, 0)
      Else
        IsEqual = Round(v1, i) = Round(v2, i)
      End If
    End Function
    Regards,
    Vladimir
    Last edited by ZVI; 02-02-2010 at 05:05 PM.

  5. #5
    VBAX Contributor
    Joined
    Dec 2009
    Location
    Sevastopol
    Posts
    150
    Location
    And this one is for comparing of the doubles in its full range with required significant digits.
    
    Function IsEqual(v1#, v2#, Optional SignificantDigits% = 12) As Boolean
      Dim f$
      If v1 = v2 Then
        IsEqual = True
      Else
        f = String(SignificantDigits, "0") & "E+0"
        IsEqual = Format(v1, f) = Format(v2, f)
      End If
    End Function
    
    Sub Test()
      Dim v1#, v2#
      v1 = 1.23456789012345E+100
      v2 = 1.23456789012346E+100
      Debug.Print IsEqual(v1, v2)     ' <- SignificantDigits = 12 as default
      Debug.Print IsEqual(v1, v2, 14) ' = True
      Debug.Print IsEqual(v1, v2, 15) ' = False
    End Sub

  6. #6
    Moderator VBAX Wizard Aussiebear's Avatar
    Joined
    Dec 2005
    Location
    Queensland
    Posts
    5,059
    Location
    Good point ZVI, however the depth of accuracy may well depend on the acceptable standards within any particular industry.
    Remember To Do the Following....
    Use [Code].... [/Code] tags when posting code to the thread.
    Mark your thread as Solved if satisfied by using the Thread Tools options.
    If posting the same issue to another forum please show the link

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •