double problem

Discussion in 'C++' started by Nomak, Aug 26, 2004.

  1. Nomak

    Nomak Guest

    Hello,

    i've lost about hours (at least) to find a problem. I use the
    following utility function:

    13 template <typename T>
    14 inline
    15 T
    16 diffabs(T a, T b)
    17 {
    18 T ret;
    19
    20 if (a > b)
    21 ret = a - b;
    22 else
    23 ret = b - a;
    24
    25 if (ret < 0)
    26 cerr << "ERROR: diffabs(" << a << ", "
    27 << b << ") = " << ret << endl;
    28
    29 assert(ret >= 0);
    30 return ret;
    31 }

    The verification part have been added after founding the bug.

    At runtime, i have the assertion wich fails, but no error message, so
    i run gdb:

    #7 0x08050747 in diffabs<double> (a=-nan(0x8000000000000), b=-1)
    29 assert(ret >= 0);
    (gdb) print ret
    $1 = -nan(0x8000000000000)

    I don't even know wich path is taken. But the error message test fails
    (<0) while the assert test is ok (>=0).

    Please tell me it's not the way it should be and it's a compiler bug.

    If it's the standard way, do you know why? And how can i detect if a
    double if negativ or -nan ?

    TIA

    --
    Nomak
     
    Nomak, Aug 26, 2004
    #1
    1. Advertising

  2. Nomak

    Nomak Guest

    Le 26/08/2004 à 08:59:39, Nomak <> a écrit:

    > Hello,
    >
    > i've lost about hours (at least) to find a problem. I use the
    > following utility function:
    >
    > 13 template <typename T>
    > 14 inline
    > 15 T
    > 16 diffabs(T a, T b)
    > 17 {
    > 18 T ret;
    > 19
    > 20 if (a > b)
    > 21 ret = a - b;
    > 22 else
    > 23 ret = b - a;
    > 24
    > 25 if (ret < 0)
    > 26 cerr << "ERROR: diffabs(" << a << ", "
    > 27 << b << ") = " << ret << endl;
    > 28
    > 29 assert(ret >= 0);
    > 30 return ret;
    > 31 }
    >
    > The verification part have been added after founding the bug.
    >
    > At runtime, i have the assertion wich fails, but no error message, so
    > i run gdb:
    >
    > #7 0x08050747 in diffabs<double> (a=-nan(0x8000000000000), b=-1)
    > 29 assert(ret >= 0);
    > (gdb) print ret
    > $1 = -nan(0x8000000000000)
    >
    > I don't even know wich path is taken. But the error message test fails
    > (<0) while the assert test is ok (>=0).
    >
    > Please tell me it's not the way it should be and it's a compiler bug.
    >
    > If it's the standard way, do you know why? And how can i detect if a
    > double if negativ or -nan ?
    >
    > TIA


    ok, i've seen the faq, too bad

    --
    Nomak
    Even if a samurai's head were to be suddenly cut off, he
    should still be able to perform one more action with certainty.
     
    Nomak, Aug 26, 2004
    #2
    1. Advertising

  3. Nomak

    Kai-Uwe Bux Guest

    Nomak wrote:

    > Hello,
    >
    > i've lost about hours (at least) to find a problem. I use the
    > following utility function:
    >
    > 13 template <typename T>
    > 14 inline
    > 15 T
    > 16 diffabs(T a, T b)
    > 17 {
    > 18 T ret;
    > 19
    > 20 if (a > b)
    > 21 ret = a - b;
    > 22 else
    > 23 ret = b - a;
    > 24
    > 25 if (ret < 0)
    > 26 cerr << "ERROR: diffabs(" << a << ", "
    > 27 << b << ") = " << ret << endl;
    > 28
    > 29 assert(ret >= 0);
    > 30 return ret;
    > 31 }
    >
    > The verification part have been added after founding the bug.
    >
    > At runtime, i have the assertion wich fails, but no error message, so
    > i run gdb:
    >
    > #7 0x08050747 in diffabs<double> (a=-nan(0x8000000000000), b=-1)
    > 29 assert(ret >= 0);
    > (gdb) print ret
    > $1 = -nan(0x8000000000000)
    >


    The assertion fails and you do not see the error message. The reason is that
    the value of ret is "not_a_number". This particular value does not compare
    the usual way:

    #include <limits>
    #include <iostream>

    int main ( void ) {
    double nan = std::numeric_limits<double>::quiet_NaN();
    std::cout << ( nan < 0 ) << "\n"
    << ( nan > 0 ) << "\n"
    << ( nan <= 0 ) << "\n"
    << ( nan >= 0 ) << "\n"
    << ( nan >= 0 ) << "\n"
    << ( nan < nan ) << "\n"
    << ( nan > nan ) << "\n"
    << ( nan == nan ) << "\n"
    << ( nan <= nan ) << "\n"
    << ( nan >= nan ) << "\n";
    }

    output:

    0
    0
    0
    0
    0
    0
    0
    0
    0
    0

    And this output is expected.

    > I don't even know wich path is taken. But the error message test fails
    > (<0) while the assert test is ok (>=0).
    >
    > Please tell me it's not the way it should be and it's a compiler bug.
    >
    > If it's the standard way, do you know why? And how can i detect if a
    > double if negativ or -nan ?
    >
    > TIA
    >


    One way to check for nan is to use the fact that !( nan == nan ) is true.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Aug 26, 2004
    #3
  4. Nomak

    Matthew Hall Guest

    Kai-Uwe Bux wrote:
    .....
    >
    > One way to check for nan is to use the fact that !( nan == nan ) is true.
    >
    >
    > Best
    >
    > Kai-Uwe Bux


    Just a note - there are compilers/platforms where (x==x) returns true
    even if x is nan - the mipspro compiler (at least the 7.3.2.1m version
    installed here) is one such example, even with all optimizations
    disabled. If you care about portability to such machines, you may wish
    to use 'isnan(x)' as defined in cmath (or math.h on Irix machines). I
    have no idea of the relative speed of isnan to (x==x), but I do know
    isnan can be slow (somewhat slower than floating point division on my
    intel boxes w/linux).

    -matt
     
    Matthew Hall, Aug 26, 2004
    #4
    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. Web learner

    from List <double> to double[]

    Web learner, Apr 25, 2006, in forum: ASP .Net
    Replies:
    3
    Views:
    484
  2. sb
    Replies:
    4
    Views:
    308
    Alberto Barbati
    Feb 19, 2004
  3. Jacek Dziedzic
    Replies:
    5
    Views:
    385
    Old Wolf
    Apr 8, 2004
  4. ferran
    Replies:
    9
    Views:
    3,038
    Kevin Goodsell
    Apr 12, 2004
  5. Sydex
    Replies:
    12
    Views:
    6,506
    Victor Bazarov
    Feb 17, 2005
Loading...

Share This Page