checking for close enough floating point values.

Discussion in 'C Programming' started by pereges, May 29, 2008.

  1. pereges

    pereges Guest

    Let's say I have two doubles:

    double a, b;

    a = 9.35678910034592
    b = 9.35678925602334

    Obviously, a < b but lets say I just want to check up to 6 places
    after the decimal. I want to check if the condition a >= b is
    satisfied. I have a tolerance value:

    #define EPSILON 0.000001

    Is this a good way to check for a >= b

    if( fabs(a-b) <= EPSILON)
    ....
    pereges, May 29, 2008
    #1
    1. Advertising

  2. pereges

    Guest

    On May 29, 8:30 pm, pereges <> wrote:
    > Let's say I have two doubles:
    >
    > double a, b;
    >
    > a = 9.35678910034592
    > b = 9.35678925602334
    >
    > Obviously, a < b but lets say I just want to check up to 6 places
    > after the decimal. I want to check if the condition a >= b is
    > satisfied. I have a tolerance value:
    >
    > #define EPSILON 0.000001
    >
    > Is this a good way to check for a >= b
    >
    > if( fabs(a-b) <= EPSILON)
    > ...

    Question 14.5 of the C-FAQ.
    <http://c-faq.com/>
    , May 29, 2008
    #2
    1. Advertising

  3. In article <>,
    pereges <> wrote:
    >Let's say I have two doubles:


    >double a, b;


    >a = 9.35678910034592
    >b = 9.35678925602334


    >Obviously, a < b but lets say I just want to check up to 6 places
    >after the decimal. I want to check if the condition a >= b is
    >satisfied. I have a tolerance value:


    >#define EPSILON 0.000001


    >Is this a good way to check for a >= b


    >if( fabs(a-b) <= EPSILON)
    >...


    That is a typical way to check whether values are "close enough"
    to being equal.

    However, you should be aware that this is -not- a test for
    equality up to the 6th decimal place. There is no exact representation
    for 0.000001 in binary floating point arithmetic, so chances
    are that instead if you use that EPSILON, what you will end up doing is
    checking whether they are equal to within
    9.99999999999999954748111825886258685613938723690807819366455078125e-07

    That's a number slightly less than 0.000001. This could make a difference
    if your a and b values were (for example) on the order of .00009 themselves.

    --
    "Beauty, like all other qualities presented to human experience,
    is relative; and the definition of it becomes unmeaning and
    useless in proportion to its abstractness." -- Walter Pater
    Walter Roberson, May 29, 2008
    #3
  4. On Thu, 29 May 2008 10:30:49 -0700 (PDT), pereges <>
    wrote:

    >Let's say I have two doubles:
    >
    >double a, b;
    >
    >a = 9.35678910034592
    >b = 9.35678925602334
    >
    >Obviously, a < b but lets say I just want to check up to 6 places
    >after the decimal. I want to check if the condition a >= b is
    >satisfied. I have a tolerance value:
    >
    >#define EPSILON 0.000001
    >
    >Is this a good way to check for a >= b
    >
    >if( fabs(a-b) <= EPSILON)
    >...


    This checks for a == b, not a >= b.

    if (a + EPSILON >= b) would be the corresponding check for >=.

    However, you should read 14.5 in the c-faq (www.c-faq.com) to see why
    an unscaled EPSILON is a bad idea.


    Remove del for email
    Barry Schwarz, May 30, 2008
    #4
  5. pereges

    pereges Guest

    On May 30, 9:52 am, Barry Schwarz <> wrote:

    > This checks for a == b, not a >= b.
    >
    > if (a + EPSILON >= b) would be the corresponding check for >=.
    >
    > However, you should read 14.5 in the c-faq (www.c-faq.com) to see why
    > an unscaled EPSILON is a bad idea.


    So do you think it will be better to use the relative difference
    method as suggested in the C faq 14.5 ?

    #define Abs(x) ((x) < 0 ? -(x) : (x))
    #define Max(a, b) ((a) > (b) ? (a) : (b))

    double RelDif(double a, double b)
    {
    double c = Abs(a);
    double d = Abs(b);

    d = Max(c, d);

    return d == 0.0 ? 0.0 : Abs(a - b) / d;
    }


    ....
    to check for a >= b,

    if(RelDif(a, b) <= TOLERANCE || a > b)
    ...

    Btw the floating point data that I'm reading has 6 places after the
    decimal point so I though I would take a tolerance value of 0.000001.
    pereges, May 30, 2008
    #5
  6. pereges

    pereges Guest

    I don't know why a seperate macro has been written for finding
    absolute value. Was it not possible to use fabs() ?

    #define Abs(x) ((x) < 0 ? -(x) : (x))
    pereges, May 30, 2008
    #6
  7. pereges

    Bartc Guest

    "Barry Schwarz" <> wrote in message
    news:...
    > On Thu, 29 May 2008 10:30:49 -0700 (PDT), pereges <>
    > wrote:
    >
    >>Let's say I have two doubles:
    >>
    >>double a, b;
    >>
    >>a = 9.35678910034592
    >>b = 9.35678925602334
    >>
    >>Obviously, a < b but lets say I just want to check up to 6 places
    >>after the decimal. I want to check if the condition a >= b is
    >>satisfied. I have a tolerance value:
    >>
    >>#define EPSILON 0.000001
    >>
    >>Is this a good way to check for a >= b
    >>
    >>if( fabs(a-b) <= EPSILON)
    >>...

    >
    > This checks for a == b, not a >= b.
    >
    > if (a + EPSILON >= b) would be the corresponding check for >=.


    What about:

    if ( a>b || (fabs(a-b)<=EPSILON) )

    for a>=b ? This would be faster when a is normally expected to be greater
    than b.

    --
    Bartc
    Bartc, May 30, 2008
    #7
  8. On Fri, 30 May 2008 02:07:53 -0700 (PDT), pereges <>
    wrote:

    >On May 30, 9:52 am, Barry Schwarz <> wrote:
    >
    >> This checks for a == b, not a >= b.
    >>
    >> if (a + EPSILON >= b) would be the corresponding check for >=.
    >>
    >> However, you should read 14.5 in the c-faq (www.c-faq.com) to see why
    >> an unscaled EPSILON is a bad idea.

    >
    >So do you think it will be better to use the relative difference
    >method as suggested in the C faq 14.5 ?
    >


    snip

    >Btw the floating point data that I'm reading has 6 places after the
    >decimal point so I though I would take a tolerance value of 0.000001.


    If you can guarantee that all the data will be within a certain range
    then you don't need to scale based on the current value. But what
    happens when one set of values is near 1e-6 and another is near 1e10?
    That is the point I thought the faq was trying to make.


    Remove del for email
    Barry Schwarz, May 31, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. H aka N
    Replies:
    15
    Views:
    15,612
    Ben Jones
    Mar 2, 2006
  2. pereges
    Replies:
    8
    Views:
    324
    Flash Gordon
    Jul 22, 2008
  3. pereges
    Replies:
    3
    Views:
    342
    ~Glynne
    Jul 23, 2008
  4. Saraswati lakki
    Replies:
    0
    Views:
    1,287
    Saraswati lakki
    Jan 6, 2012
  5. teeshift
    Replies:
    2
    Views:
    241
    Chris Pearl
    Dec 1, 2006
Loading...

Share This Page