dcsimg
Results 1 to 8 of 8

Thread: Inexact floating point representations

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Nov 2018
    Posts
    206

    Inexact floating point representations

    What is the correct way to deal with this problem?

    I have this line of code:

    If thisMeasureTime <> measureTime Then

    In my mind as it appears in my code I am expecting both variables to be 1
    but it must be 0.999999999 vs 1

    I changed the above test to

    If Abs(thisMeasureTime - measureTime) >= 0.000001 Then

    and it works as I expect.

    Have I dealt with this correctly,
    or have I just produced a kludge that works, and there is a proper way to deal with this?

  2. #2
    Lively Member
    Join Date
    May 2017
    Posts
    73

    Re: Inexact floating point representations

    Floating numbers are stored as binary fractions. This means they cannot hold an exact representation of any quantity that is not a binary fraction (of the form k / (2 ^ n) where k and n are integers). For example, 0.5 (= 1/2) and 0.3125 (= 5/16) can be held as precise values, whereas 0.2 (= 1/5) and 0.3 (= 3/10) can be only approximations.

    So your 'kludge' is both appropriate and necessary to get a meaningful comparison of floats.

    While we're at it, remember any operations on floats (+, -, /, *, etc) - not just comparisons - can also lead to annoying rounding errors and must be coded for appropriately.

  3. #3
    Frenzied Member wqweto's Avatar
    Join Date
    May 2011
    Posts
    1,682

    Re: Inexact floating point representations

    Quote Originally Posted by mms_ View Post
    Have I dealt with this correctly,
    or have I just produced a kludge that works, and there is a proper way to deal with this?
    This is the proper way to deal with floating-point comparisons -- by using a Private Const EPSILON As Double = 0.000001 for the margin of rounding errors.

    a = b becomes Abs(a - b) < EPSILON
    a <> b becomes Abs(a - b) > EPSILON
    a < 0 becomes a < -EPSILON
    a <= 0 becomes a < EPSILON
    a < b becomes a < b - EPSILON
    a <= b becomes a < b + EPSILON

    Cannot come up with more examples now but you can use common sense when faced with different use-cases.

    cheers,
    </wqw>

  4. #4

    Thread Starter
    Addicted Member
    Join Date
    Nov 2018
    Posts
    206

    Re: Inexact floating point representations

    OK thanks guys

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,948

    Re: Inexact floating point representations

    mms_, basically, you did it correctly. And personally, I wouldn't call that particular case a kludge. It just appreciates the sometimes peculiar nature of IEEE numbers.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  6. #6
    Hyperactive Member
    Join Date
    Feb 2017
    Posts
    458

    Re: Inexact floating point representations

    Sadly, EPSILON does Not afford a simple solution for Database dates (a double) when "Seeking" (a = compare). One either has a Match or a NoMatch
    with no way to compare until after the Seek.

  7. #7
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,528

    Re: Inexact floating point representations

    Quote Originally Posted by vb6forever View Post
    Sadly, EPSILON does Not afford a simple solution for Database dates (a double) when "Seeking" (a = compare). One either has a Match or a NoMatch
    with no way to compare until after the Seek.
    SQL (as a language) offers all the comparison-options wqweto listed further above.

    Your "Seeking" is only "reduced client-functionality", usually offered by clientside Result-Set-Wrappers (e.g. DAO-Recordset-Seeks, or ADO-Rs-Filter-Methods) -
    and therefore often limited with regards to the complexity of "allowed boolean expressions" ...
    (which are easily handled without limitations in the Where-Clauses of "full SQL-parsers/interpreters" of the DBEngine-Cores).

    Olaf

  8. #8
    Hyperactive Member
    Join Date
    Feb 2017
    Posts
    458

    Re: Inexact floating point representations

    Olaf:
    Thanks for pointing out that "Seeking" is "reduced functionality".

    I do a lot of DAO table Seeks on DateTime fields and never understood why
    "Seek" didn't offer this capability. Seems like going around the block to
    query the table, make the comparison, and then if equal -- but off enough because of the float precision the record is considered a new record to the DB --, having to adjust the datetime value being compared, in order to edit the table record.

    Here's a little example using EPSILON (at .0000001) when things appear equal (d1 and d2 are displayed the same) but internally they are NOT, and the databases normally interpret them as NOT equal.

    Code:
    Private Sub Form_Load()
    
       Dim d1 As Date
       Dim d2 As Date
       Dim n1 As Double
       Dim n2 As Double
       
       d1 = #1/10/2020 3:30:33 AM#
       n1 = CDbl(d1)
       
       n2 = n1 + 0.0000001
       d2 = CDate(n2)
    
       MsgBox "d1: " & d1 & vbCRLF & "d2: " & d2
       
       If n1 = n2 Then
          MsgBox "Dates Match"
       Else
          MsgBox "NoMatch  " & vbCRLF & "n1: " & n1 & vbCRLF & "n2: " & n2
       End If
    
    End Sub
    Good Links:
    https://floating-point-gui.de/errors/comparison/
    https://bitbashing.io/comparing-floats.html
    Last edited by vb6forever; Jan 17th, 2020 at 04:18 PM.

Posting Permissions

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



Featured


Click Here to Expand Forum to Full Width