Regarding Q. 14-5

Discussion in 'C Programming' started by Brian Dude, Dec 3, 2005.

  1. Brian Dude

    Brian Dude Guest

    Hello, I understand the part about not comparing two floating-point
    numbers for exact-ness. Does this also apply to comparisons to constants?
    i.e.:

    double f;

    if ( f <= 1.0){
    ...
    }

    TIA,
    Brian
     
    Brian Dude, Dec 3, 2005
    #1
    1. Advertising

  2. Brian Dude

    pete Guest

    Brian Dude wrote:
    >
    > Hello, I understand the part
    > about not comparing two floating-point
    > numbers for exact-ness.


    Your example doesn't show it.
    There's nothing wrong with comparing two doubles
    with a relational operator.

    > Does this also apply to comparisons to constants?
    > i.e.:
    >
    > double f;
    >
    > if ( f <= 1.0){
    > ...
    > }


    --
    pete
     
    pete, Dec 3, 2005
    #2
    1. Advertising

  3. Brian Dude

    Flash Gordon Guest

    pete wrote:
    > Brian Dude wrote:
    >> Hello, I understand the part
    >> about not comparing two floating-point
    >> numbers for exact-ness.

    >
    > Your example doesn't show it.
    > There's nothing wrong with comparing two doubles
    > with a relational operator.
    >
    >> Does this also apply to comparisons to constants?
    >> i.e.:
    >>
    >> double f;
    >>
    >> if ( f <= 1.0){
    >> ...
    >> }


    However, something like
    if (f == CONSTANT)

    would be bad, because:
    1) If f is calculated (and why else would it be a variable) it might not
    be exactly CONSTANT even if an infinite precision system said it was.
    2) For some values CONSTANT won't be exactly what you think.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
     
    Flash Gordon, Dec 3, 2005
    #3
  4. On Sat, 03 Dec 2005 06:32:03 GMT, in comp.lang.c , pete
    <> wrote:

    >Brian Dude wrote:
    >>
    >> Hello, I understand the part
    >> about not comparing two floating-point
    >> numbers for exact-ness.

    >
    >Your example doesn't show it.
    >There's nothing wrong with comparing two doubles
    >with a relational operator.


    Except that even when equal as far as expectation is concerned, they
    might compare unequal.

    #include <stdio.h>
    #include <math.h>

    int main(void)
    {
    double x = acos(0);

    x=cos(((x*123.4567)-100)/123.4567 +100/123.4567);

    printf("%s\n", x==0.0?"equal":"different");

    return 0;
    }

    >> Does this also apply to comparisons to constants?
    >> if ( f <= 1.0){


    Since at least one of the two objects being compared cannot be a
    constant, yes. Obviously you're a bit safer with lessthan/morethan but
    you could still be surprised - delta can be both positive and negative
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Dec 3, 2005
    #4
  5. Brian Dude

    pete Guest

    Mark McIntyre wrote:
    >
    > On Sat, 03 Dec 2005 06:32:03 GMT, in comp.lang.c , pete
    > <> wrote:
    >
    > >Brian Dude wrote:
    > >>
    > >> Hello, I understand the part
    > >> about not comparing two floating-point
    > >> numbers for exact-ness.

    > >
    > >Your example doesn't show it.
    > >There's nothing wrong with comparing two doubles
    > >with a relational operator.

    >
    > Except that even when equal as far as expectation is concerned, they
    > might compare unequal.


    > printf("%s\n", x==0.0?"equal":"different");


    == is an equality operator.
    == is not a relational operator.

    > >> Does this also apply to comparisons to constants?
    > >> if ( f <= 1.0){


    <= is a relational operator.
    <= is not an equality operator.

    --
    pete
     
    pete, Dec 3, 2005
    #5
  6. Brian Dude

    Malcolm Guest

    "Brian Dude" <> wrote
    > Hello, I understand the part about not comparing two floating-point
    > numbers for exact-ness. Does this also apply to comparisons to constants?
    > i.e.:
    >
    > double f;
    >
    > if ( f <= 1.0){
    > ...
    > }
    >

    That is dangerous.
    f may be mathematically equal to 1, but slightly bigger because of floating
    point unit errors (eg if it is the length of a unit vector, calculated with
    a call to sqrt()).
     
    Malcolm, Dec 3, 2005
    #6
  7. Brian Dude

    Eric Sosman Guest

    Malcolm wrote:

    > "Brian Dude" <> wrote
    >
    >>Hello, I understand the part about not comparing two floating-point
    >>numbers for exact-ness. Does this also apply to comparisons to constants?
    >>i.e.:
    >>
    >>double f;
    >>
    >>if ( f <= 1.0){
    >>...
    >>}
    >>

    >
    > That is dangerous.
    > f may be mathematically equal to 1, but slightly bigger because of floating
    > point unit errors (eg if it is the length of a unit vector, calculated with
    > a call to sqrt()).


    Malcolm raises an important problem, but does not show
    how to solve it. The solution is to compare not to 1.0 but
    to 1.0 plus a suitable error tolerance:

    if ( f <= 1.0 + epsilon )

    Unfortunately, this is just as dangerous as the original,
    because f might be mathematically equal to 1+epsilon but
    slightly bigger because of floating point errors. To allow
    for that possibility, the test should be written as

    if ( f <= 1.0 + 2.0 * epsilon )

    This is still dangerous, because f might be mathematically
    equal to 1+2*epsilon but slightly bigger because of floating
    point errors. The same objection applies to 1+N*epsilon for
    any finite N, so the only recourse is to allow for a possibly
    infinite amount of inaccuracy in the floating-point calculation:

    #include <math.h>
    ...
    if (f <= 1.0 + INFINITY )

    This solution should meet Malcolm's objections.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Dec 3, 2005
    #7
  8. Brian Dude

    Flash Gordon Guest

    Eric Sosman wrote:
    > Malcolm wrote:
    >
    >> "Brian Dude" <> wrote
    >>
    >>> Hello, I understand the part about not comparing two floating-point
    >>> numbers for exact-ness. Does this also apply to comparisons to
    >>> constants?
    >>> i.e.:
    >>>
    >>> double f;
    >>>
    >>> if ( f <= 1.0){
    >>> ...
    >>> }
    >>>

    >>
    >> That is dangerous.
    >> f may be mathematically equal to 1, but slightly bigger because of
    >> floating point unit errors (eg if it is the length of a unit vector,
    >> calculated with a call to sqrt()).

    >
    > Malcolm raises an important problem, but does not show
    > how to solve it. The solution is to compare not to 1.0 but
    > to 1.0 plus a suitable error tolerance:
    >
    > if ( f <= 1.0 + epsilon )


    <snip>

    You forgot the possibility that f may be mathematically slightly bigger
    than 1.0 but due to floating point errors be slightly smaller, to avoid
    this you should do:
    if (f <= 1.0-epsilon) {
    /* it's smaller or equal */
    }
    else if (f <= 1.0+epsilon) {
    /* not sure */
    }
    else {
    /* it's larger */
    }

    > #include <math.h>
    > ...
    > if (f <= 1.0 + INFINITY )
    >
    > This solution should meet Malcolm's objections.


    Then following through with your argument we get:
    if (f <= 1.0-INFINITY ) {
    /* it's smaller or equal */
    }
    else if (f <= 1.0+INFINITY) {
    /* not sure */
    }
    else {
    /* it's larger */
    }

    :)
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
     
    Flash Gordon, Dec 3, 2005
    #8
  9. On Sat, 03 Dec 2005 15:09:32 -0500, in comp.lang.c , Eric Sosman
    <> wrote:

    > Malcolm raises an important problem, but does not show
    >how to solve it.


    Eric raises an important problem with any solution, but fails to show
    how to solve it :)

    The solution is indeed to compare to 1+epsilon, but to define epsilon
    suitably for your application. Its likely for instance that if you're
    doing calcs that involve rounding to 5dp, then a comparison to 4dp
    will succeed. If you're doing the sum I did earlier, then epsilon
    could be 1e-10 and that'd be successful.

    The precise method of determining epsilon is left as an exercise for
    the reader.
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Dec 3, 2005
    #9
  10. In article <> Eric Sosman <> writes:
    > Malcolm wrote:

    [ About f <= 1.0 ]
    > > That is dangerous.
    > > f may be mathematically equal to 1, but slightly bigger because of
    > > floating point unit errors (eg if it is the length of a unit vector,
    > > calculated with a call to sqrt()).


    In that case we have a false negative.

    > Malcolm raises an important problem, but does not show
    > how to solve it. The solution is to compare not to 1.0 but
    > to 1.0 plus a suitable error tolerance:
    > if ( f <= 1.0 + epsilon )
    > Unfortunately, this is just as dangerous as the original,
    > because f might be mathematically equal to 1+epsilon but
    > slightly bigger because of floating point errors.


    This is different. We want to compare with 1.0, and add epsilon toe
    avoid false negatives. But in this case we get a true negative.
    On the other hand, if f is mathematially greater than 1+epsilon,
    but slightly smaller due to floating point errors we get a false
    positive...

    But indeed, comparing to 1.0 + epsilon is just as silly as comparing
    to plain 1.0. The bottom line is that when you want to use
    floating-point you better know what you are doing so that you can
    judge how you wish to compare. (In all my years of programming in
    numerical mathematics I rarely, if at all, coded a line like
    f <= 1.0 + epsilon, but many lines like f <= 1.0.)
    --
    dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
    home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
     
    Dik T. Winter, Dec 3, 2005
    #10
  11. Brian Dude

    Eric Sosman Guest

    Mark McIntyre wrote:

    > On Sat, 03 Dec 2005 15:09:32 -0500, in comp.lang.c , Eric Sosman
    > <> wrote:
    >
    >
    >> Malcolm raises an important problem, but does not show
    >>how to solve it.

    >
    >
    > Eric raises an important problem with any solution, but fails to show
    > how to solve it :)
    >
    > The solution is indeed to compare to 1+epsilon, but to define epsilon
    > suitably for your application. Its likely for instance that if you're
    > doing calcs that involve rounding to 5dp, then a comparison to 4dp
    > will succeed. If you're doing the sum I did earlier, then epsilon
    > could be 1e-10 and that'd be successful.
    >
    > The precise method of determining epsilon is left as an exercise for
    > the reader.


    What I was trying to point out is that the supposed
    "solution" is no solution at all. For example,

    if ( f <= 1.0 )
    angle = asin(f);

    is not improved by replacing 1.0 with 1.0+epsilon ...

    The solution -- to the degree that one exists -- is
    to use care in calculating f in the first place, and to
    understand the nature of the errors that occur along the
    way and the manner in which they grow and decay. That
    field of study is called Numerical Analysis, and is too
    rich a topic to be treated at any depth in Usenet postings.

    However, the fact that floating-point numbers are usually
    (but not always!) approximations and that floating-point
    calculations usually (but not always!) involve error should
    not be taken as meaning that all floating-point comparisions
    are "dangerous!"

    I once read (but cannot now find) a description of a
    progression of attitudes that may apply here:

    1. Initially, people trust every digit of every number
    a computer calculates.

    2. Having learned that some (even many) digits can be
    incorrect, the once-burned-twice-shy crowd overreacts
    by never trusting any floating-point calculation.

    3. With further experience and study, a more rational
    (pun intentional) attitude of tolerance (ditto)
    eventually develops. Floating-point arithmetic is
    imperfect (as is int arithmetic) but like many other
    tools is useful if handled with care.

    It seems to me that someone whose alarm bells clang at `f<=1.0'
    may not have completed the journey from stage 2 to 3. Malcolm
    is probably at 2+epsilon or 3-delta, but afraid to calculate the
    remaining distance ;-)

    Recommended (strongly recommended) reading: "What Every
    Computer Scientist Should Know About Floating-Point Arithmetic"
    by David Goldberg, widely archived on the Web.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Dec 3, 2005
    #11
  12. On Sat, 03 Dec 2005 18:29:30 -0500, in comp.lang.c , Eric Sosman
    <> wrote:

    >
    > What I was trying to point out is that the supposed
    >"solution" is no solution at all.


    I realise that, but my point is that you're wrong. :)

    >For example,
    >
    > if ( f <= 1.0 )
    > angle = asin(f);
    >
    >is not improved by replacing 1.0 with 1.0+epsilon ...


    Of course it is. You just need to choose epsilon carefully, and decide
    how to handle failures. The choice of both is highly dependent on how
    you arrived at the FP value you want to examine, and how you want to
    handle the problem cases.

    #define EPS -1e-12

    if ( f <= 1.0+EPS )
    angle = asin(f);
    else
    {
    puts("f ->1");
    f = asin(1.0);
    }

    > Recommended (strongly recommended) reading: "What Every
    >Computer Scientist Should Know About Floating-Point Arithmetic"
    >by David Goldberg, widely archived on the Web.


    Absolutely.
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Dec 3, 2005
    #12
  13. Brian Dude

    pete Guest

    Mark McIntyre wrote:
    >
    > On Sat, 03 Dec 2005 15:09:32 -0500, in comp.lang.c , Eric Sosman
    > <> wrote:
    >
    > > Malcolm raises an important problem, but does not show
    > >how to solve it.

    >
    > Eric raises an important problem with any solution, but fails to show
    > how to solve it :)
    >
    > The solution is indeed to compare to 1+epsilon, but to define epsilon
    > suitably for your application.


    It depends on what you're doing.

    In the very few times that I have written code
    which compares a double variable against a double constant
    with either a relational operator or an equality operator,
    it would be inappropriate to make use of DBL_EPSILON.
    The (DBL_MAX >= x && x > 0) expression, is correct as is,
    and so is the (0 != x) expression.

    double sssqrt(double x)
    {
    if (DBL_MAX >= x && x > 0) {
    const double a = x;
    double b = x / 2 + 0.5;

    do {
    x = b;
    b = (a / x + x) / 2;
    } while (x > b);
    } else {
    if (0 != x) {
    errno = EDOM;
    x = HUGE_VAL;
    }
    }
    return x;
    }

    In reviewing my toy math library, I've noticed that
    I don't have any code which compares two double variables
    with an equality operator.

    All of my epsilon usage is kind of like this:

    static double p_i(void)
    {
    unsigned n;
    double p, a, b;

    p = 0;
    a = 3;
    n = 1;
    do {
    a /= 9;
    b = a / n;
    a /= 9;
    n += 2;
    b -= a / n;
    n += 2;
    p += b;
    } while (b > DBL_EPSILON / 4);
    a = 2;
    n = 1;
    do {
    a /= 4;
    b = a / n;
    a /= 4;
    n += 2;
    b -= a / n;
    n += 2;
    p += b;
    } while (b > DBL_EPSILON / 2);
    return 4 * p;
    }

    --
    pete
     
    pete, Dec 3, 2005
    #13
  14. pete wrote:
    > == is not a relational operator.


    ?


    August

    --
    I am the "ILOVEGNU" signature virus. Just copy me to your
    signature. This email was infected under the terms of the GNU
    General Public License.
     
    August Karlstrom, Dec 4, 2005
    #14
  15. Brian Dude

    Ben Pfaff Guest

    August Karlstrom <> writes:

    > pete wrote:
    >> == is not a relational operator.

    >
    > ?


    6.5.8 Relational operators
    Syntax
    1 relational-expression:
    shift-expression
    relational-expression < shift-expression
    relational-expression > shift-expression
    relational-expression <= shift-expression
    relational-expression >= shift-expression

    [...]

    6.5.9 Equality operators
    Syntax
    1 equality-expression:
    relational-expression
    equality-expression == relational-expression
    equality-expression != relational-expression

    --
    int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    );}return 0;}
     
    Ben Pfaff, Dec 4, 2005
    #15
  16. On Sat, 03 Dec 2005 23:59:57 GMT, in comp.lang.c , pete
    <> wrote:

    >Mark McIntyre wrote:
    >
    >> The solution is indeed to compare to 1+epsilon, but to define epsilon
    >> suitably for your application.

    >
    >it would be inappropriate to make use of DBL_EPSILON.


    Note carefully that I did not say DBL_EPSILON.
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Dec 4, 2005
    #16
  17. Brian Dude

    pete Guest

    Mark McIntyre wrote:
    >
    > On Sat, 03 Dec 2005 23:59:57 GMT, in comp.lang.c , pete
    > <> wrote:
    >
    > >Mark McIntyre wrote:
    > >
    > >> The solution is indeed to compare
    > >> to 1+epsilon, but to define epsilon
    > >> suitably for your application.

    > >
    > >it would be inappropriate to make use of DBL_EPSILON.

    >
    > Note carefully that I did not say DBL_EPSILON.


    I would say that in cases
    where a suitable definition of epsilon, is zero,
    that the use of epsilon isn't required.

    --
    pete
     
    pete, Dec 4, 2005
    #17
  18. Ben Pfaff wrote:
    > August Karlstrom <> writes:
    >
    >
    >>pete wrote:
    >>
    >>>== is not a relational operator.

    >>
    >>?

    >
    >
    > 6.5.8 Relational operators
    > Syntax
    > 1 relational-expression:
    > shift-expression
    > relational-expression < shift-expression
    > relational-expression > shift-expression
    > relational-expression <= shift-expression
    > relational-expression >= shift-expression
    >
    > [...]
    >
    > 6.5.9 Equality operators
    > Syntax
    > 1 equality-expression:
    > relational-expression
    > equality-expression == relational-expression
    > equality-expression != relational-expression
    >


    OK, that's weird. Still `==' works as a relational operator in the
    common (mathematical) sense.


    August

    --
    I am the "ILOVEGNU" signature virus. Just copy me to your
    signature. This email was infected under the terms of the GNU
    General Public License.
     
    August Karlstrom, Dec 4, 2005
    #18
  19. Brian Dude

    Skarmander Guest

    August Karlstrom wrote:
    > Ben Pfaff wrote:
    >> August Karlstrom <> writes:
    >>
    >>
    >>> pete wrote:
    >>>
    >>>> == is not a relational operator.
    >>>
    >>> ?

    >>
    >>
    >> 6.5.8 Relational operators
    >> Syntax
    >> 1 relational-expression:
    >> shift-expression
    >> relational-expression < shift-expression
    >> relational-expression > shift-expression
    >> relational-expression <= shift-expression
    >> relational-expression >= shift-expression
    >>
    >> [...]
    >>
    >> 6.5.9 Equality operators
    >> Syntax
    >> 1 equality-expression:
    >> relational-expression
    >> equality-expression == relational-expression
    >> equality-expression != relational-expression
    >>

    >
    > OK, that's weird. Still `==' works as a relational operator in the
    > common (mathematical) sense.
    >

    Yes, it's a nice gotcha, isn't it? Like "byte", this is one of those terms C
    appropriates in its own way and doesn't quite mean what you'd expect it to mean.

    S.
     
    Skarmander, Dec 4, 2005
    #19
  20. Brian Dude

    pete Guest

    August Karlstrom wrote:
    >
    > Ben Pfaff wrote:
    > > August Karlstrom <> writes:
    > >
    > >
    > >>pete wrote:
    > >>
    > >>>== is not a relational operator.
    > >>
    > >>?


    > > 6.5.8 Relational operators


    > > 6.5.9 Equality operators


    > OK, that's weird. Still `==' works as a relational operator in the
    > common (mathematical) sense.


    I wrote what I wrote, plainly:

    "== is an equality operator.
    == is not a relational operator.

    <= is a relational operator.
    <= is not an equality operator."

    --
    pete
     
    pete, Dec 4, 2005
    #20
    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. pradeep kumar sharma

    regarding vb.net

    pradeep kumar sharma, Dec 3, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    495
    Miha Markic
    Dec 3, 2003
  2. ElanKathir .S.N

    Regarding Class & Object in .Net Framework

    ElanKathir .S.N, Apr 23, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    362
    Ray Cassick \(Home\)
    Apr 30, 2004
  3. Tarundeep Singh Kalra

    Regarding .NET framework requirements

    Tarundeep Singh Kalra, May 6, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    474
  4. Patrick

    Question regarding SP

    Patrick, Jan 24, 2005, in forum: ASP .Net
    Replies:
    7
    Views:
    655
    Gopinath Rajee
    Jan 25, 2005
  5. =?Utf-8?B?U2FuamVldiBCaGF0aWE=?=

    Regarding Browse information(ALT-F12) feature same as VS 6.0

    =?Utf-8?B?U2FuamVldiBCaGF0aWE=?=, Apr 6, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    891
    =?Utf-8?B?U2FuamVldiBCaGF0aWE=?=
    Apr 8, 2005
Loading...

Share This Page