checking double for Inf or NaN - how?

Discussion in 'C Programming' started by =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 18, 2006.

  1. Hi,

    I found the code below from
    http://www.blitzbasic.com/Community/posts.php?topic=55633

    ------
    ' Check if number is finite.


    Local u:Double = 2 ' also works for floats

    For Local n = 1 To 12
    Print isfinite(u) + " " + u
    u :* u
    Next

    Print
    Print "What about NaN?"
    Print

    u = u - u
    Print isfinite(u) + " " + u


    Function isfinite( x:Double ) ' assumes Intel byte order

    Const EXP_BITS = %01111111111100000000000000000000

    Local bits = ( Int Ptr Varptr x )[1] ' [0] for Mac?

    Return ( bits & EXP_BITS ) <> EXP_BITS ' exponent is all 1s for
    infinity or NaN

    End Function


    ------

    I need something like that - but the author writes that "This is intel
    only. Anybody want to make it multiplatform? It shouldn't be difficult,
    but I don't have a Mac".

    The code above doesn't look like "standard C" to me... But I would like
    this function to work *preferable* under both linux, mac and windows
    pc's....

    My guess is that the code should be changed to something like:

    int(double testval)
    {
    Const EXP_BITS = %01111111111100000000000000000000

    return (testval && EXP_BITS); /* returns either 0 or 1 ? */
    }

    But I guess EXP_BITS is completely wrong defined, so how to make it work
    - and are there better existing ways to check for Inf or NaN???

    It would be nice with 2 functions: One that tests for plus/minus Inf and
    one that checks for NaN, if there's any difference? I didn't really
    understood the bit-pattern-difference between NaN and Inf...


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 18, 2006
    #1
    1. Advertising

  2. Martin Jørgensen wrote:
    -snip-

    > It would be nice with 2 functions: One that tests for plus/minus Inf and
    > one that checks for NaN, if there's any difference? I didn't really
    > understood the bit-pattern-difference between NaN and Inf...


    Basically I have a variable that contains -1.#IND00000000000...
    according to MS visual studio 2005... I thought that this was (-inf) so
    I made a check:

    ....
    if( val < 0)
    do something <- never got here....

    I hope somebody can figure this out?


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 18, 2006
    #2
    1. Advertising

  3. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Joe Smith Guest

    "Martin Jørgensen" <> wrote in message
    news:...
    > Hi,
    >
    > I found the code below from
    > http://www.blitzbasic.com/Community/posts.php?topic=55633
    >
    > ------
    > ' Check if number is finite.
    >
    >
    > Local u:Double = 2 ' also works for floats
    >
    > For Local n = 1 To 12
    > Print isfinite(u) + " " + u
    > u :* u
    > Next
    >
    > Print
    > Print "What about NaN?"
    > Print
    >
    > u = u - u
    > Print isfinite(u) + " " + u
    >
    >
    > Function isfinite( x:Double ) ' assumes Intel byte order
    >
    > Const EXP_BITS = %01111111111100000000000000000000
    >
    > Local bits = ( Int Ptr Varptr x )[1] ' [0] for Mac?
    >
    > Return ( bits & EXP_BITS ) <> EXP_BITS ' exponent is all 1s for infinity
    > or NaN
    >
    > End Function
    >
    >
    > ------
    >
    > I need something like that - but the author writes that "This is intel
    > only. Anybody want to make it multiplatform? It shouldn't be difficult,
    > but I don't have a Mac".
    >
    > The code above doesn't look like "standard C" to me... But I would like
    > this function to work *preferable* under both linux, mac and windows
    > pc's....
    >
    > My guess is that the code should be changed to something like:
    >
    > int(double testval)
    > {
    > Const EXP_BITS = %01111111111100000000000000000000
    >
    > return (testval && EXP_BITS); /* returns either 0 or 1 ? */
    > }
    >
    > But I guess EXP_BITS is completely wrong defined, so how to make it work -
    > and are there better existing ways to check for Inf or NaN???
    >
    > It would be nice with 2 functions: One that tests for plus/minus Inf and
    > one that checks for NaN, if there's any difference? I didn't really
    > understood the bit-pattern-difference between NaN and Inf...


    The source snippet might look different to you than me, but it seems to be
    missing about ten tokens in order to be C. joe
     
    Joe Smith, May 18, 2006
    #3
  4. Martin Jørgensen wrote:
    -snip-

    > understood the bit-pattern-difference between NaN and Inf...


    Addition: You can generate -1.#IND000000... by:

    #include math.h

    ....
    var = sqrt (-10);
    ....

    var = -1.#IND000000.., according to MS visual studio 2005 (just in case
    somebody wants to try it out).


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 18, 2006
    #4
  5. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    bert Guest

    Martin Jørgensen wrote:
    > Martin Jørgensen wrote:
    > -snip-
    >
    > > It would be nice with 2 functions: One that tests for plus/minus Inf and
    > > one that checks for NaN, if there's any difference? I didn't really
    > > understood the bit-pattern-difference between NaN and Inf...

    >
    > Basically I have a variable that contains -1.#IND00000000000...
    > according to MS visual studio 2005... I thought that this was (-inf) so
    > I made a check:
    >
    > ...
    > if( val < 0)
    > do something <- never got here....
    >
    > I hope somebody can figure this out?
    > Martin Jørgensen


    The IEEE floating point standard says that any comparison
    in which one operand is a NaN should evaluate to FALSE.
    So the following counter-intuitive test meets your needs:

    if (val == val)
    do_nothing ( );
    else
    report_NaN (val);

    unless an over-eager (and incorrect) compiler optimises
    half of it away . . .
    --
     
    bert, May 18, 2006
    #5
  6. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    pete Guest

    Martin Jørgensen wrote:

    > Basically I have a variable that contains -1.#IND00000000000...
    > according to MS visual studio 2005...
    > I thought that this was (-inf) so
    > I made a check:
    >
    > ...
    > if( val < 0)
    > do something <- never got here....
    >
    > I hope somebody can figure this out?


    exp(DBL_MAX) is a range error.
    sqrt(-1) is a domain error.

    /* BEGIN new.c */

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

    int main(void)
    {
    double x = -exp(DBL_MAX);
    double y = sqrt(-1);

    printf("-exp(DBL_MAX) is %f\n", x);
    printf("sqrt(-1) is %f\n", y);
    return 0;
    }

    /* END new.c */


    N869
    7.12.1 Treatment of error conditions
    [#1] The behavior of each of the functions in <math.h> is
    specified for all representable values of its input
    arguments, except where stated otherwise.
    [#2] For all functions, a domain error occurs if an input
    argument is outside the domain over which the mathematical
    function is defined. The description of each function lists
    any required domain errors; an implementation may define
    additional domain errors, provided that such errors are
    consistent with the mathematical definition of the
    function.182) On a domain error, the function returns an
    implementation-defined value; whether the integer expression
    errno acquires the value EDOM is implementation-defined.
    [#3] Similarly, a range error occurs if the mathematical
    result of the function cannot be represented in an object of
    the specified type, due to extreme magnitude. A floating
    result overflows if the magnitude of the mathematical result
    is finite but so large that the mathematical result cannot
    be represented, without extraordinary roundoff error, in an
    object of the specified type. If a floating result
    overflows and default rounding is in effect, or if the
    mathematical result is an exact infinity (for example
    log(0.0)), then the function returns the value of the macro
    HUGE_VAL, HUGE_VALF, or HUGE_VALL according to the return
    type, with the same sign as the correct value of the
    function; whether errno acquires the value ERANGE when a
    range error occurs is implementation-defined. The result
    underflows if the magnitude of the mathematical result is so
    small that the mathematical result cannot be
    represented, without extraordinary roundoff error, in an
    object of the
    specified type. If the result underflows, the function
    returns a value whose magnitude is no greater than the
    smallest normalized positive number in the specified type
    and is otherwise implementation-defined; whether errno
    acquires the value ERANGE is implementation-defined.


    --
    pete
     
    pete, May 18, 2006
    #6
  7. pete wrote:
    > Martin Jørgensen wrote:
    >
    >
    >>Basically I have a variable that contains -1.#IND00000000000...
    >>according to MS visual studio 2005...
    >>I thought that this was (-inf) so
    >>I made a check:
    >>
    >>...
    >> if( val < 0)
    >> do something <- never got here....
    >>
    >>I hope somebody can figure this out?

    >
    >
    > exp(DBL_MAX) is a range error.
    > sqrt(-1) is a domain error.

    -snip-

    Yes, thanks but you're only printing out the values using printf(). You
    didn't make the if-test...


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 18, 2006
    #7
  8. bert wrote:
    > Martin Jørgensen wrote:
    >
    >>Martin Jørgensen wrote:
    >>-snip-
    >>
    >>
    >>>It would be nice with 2 functions: One that tests for plus/minus Inf and
    >>>one that checks for NaN, if there's any difference? I didn't really
    >>>understood the bit-pattern-difference between NaN and Inf...

    >>
    >>Basically I have a variable that contains -1.#IND00000000000...
    >>according to MS visual studio 2005... I thought that this was (-inf) so
    >>I made a check:
    >>
    >>...
    >> if( val < 0)
    >> do something <- never got here....
    >>
    >>I hope somebody can figure this out?
    >>Martin Jørgensen

    >
    >
    > The IEEE floating point standard says that any comparison
    > in which one operand is a NaN should evaluate to FALSE.
    > So the following counter-intuitive test meets your needs:
    >
    > if (val == val)
    > do_nothing ( );
    > else
    > report_NaN (val);


    Ok, thanks a lot - it works here and it was a lot easier than I
    feared... And how do I check for plus/minus inf ?


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 18, 2006
    #8
  9. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    jacob navia Guest

    Martin Jørgensen a écrit :
    > Hi,
    >
    > I found the code below from
    > http://www.blitzbasic.com/Community/posts.php?topic=55633
    >
    > ------
    > ' Check if number is finite.
    >
    >
    > Local u:Double = 2 ' also works for floats
    >
    > For Local n = 1 To 12
    > Print isfinite(u) + " " + u
    > u :* u
    > Next
    >
    > Print
    > Print "What about NaN?"
    > Print
    >
    > u = u - u
    > Print isfinite(u) + " " + u
    >
    >
    > Function isfinite( x:Double ) ' assumes Intel byte order
    >
    > Const EXP_BITS = %01111111111100000000000000000000
    >
    > Local bits = ( Int Ptr Varptr x )[1] ' [0] for Mac?
    >
    > Return ( bits & EXP_BITS ) <> EXP_BITS ' exponent is all 1s for
    > infinity or NaN
    >
    > End Function
    >
    >
    > ------
    >
    > I need something like that - but the author writes that "This is intel
    > only. Anybody want to make it multiplatform? It shouldn't be difficult,
    > but I don't have a Mac".
    >
    > The code above doesn't look like "standard C" to me... But I would like
    > this function to work *preferable* under both linux, mac and windows
    > pc's....
    >
    > My guess is that the code should be changed to something like:
    >
    > int(double testval)
    > {
    > Const EXP_BITS = %01111111111100000000000000000000
    >
    > return (testval && EXP_BITS); /* returns either 0 or 1 ? */
    > }
    >
    > But I guess EXP_BITS is completely wrong defined, so how to make it work
    > - and are there better existing ways to check for Inf or NaN???
    >
    > It would be nice with 2 functions: One that tests for plus/minus Inf and
    > one that checks for NaN, if there's any difference? I didn't really
    > understood the bit-pattern-difference between NaN and Inf...
    >
    >
    > Best regards / Med venlig hilsen
    > Martin Jørgensen
    >


    Standard C has several functions for this:
    1) isfinite: returns true if its argument is finite
    2) isinf: returns true if its argument is infinite
    3) isnormal: returns true if its argument is normal
    4) fpclassify returns the type of its argument.

    See the documentation of your compiler system.

    P.S. This will work in standard C, not in Visual Studio.
     
    jacob navia, May 18, 2006
    #9
  10. jacob navia wrote:
    -snip-

    > Standard C has several functions for this:
    > 1) isfinite: returns true if its argument is finite
    > 2) isinf: returns true if its argument is infinite
    > 3) isnormal: returns true if its argument is normal
    > 4) fpclassify returns the type of its argument.
    >
    > See the documentation of your compiler system.


    Ok.

    > P.S. This will work in standard C, not in Visual Studio.


    Is visual studio 2005 not standard C? I think I disabled something
    that's on by default so I think it understands standard C at least... At
    least I've had no problems yet with standard C on it (or is it ANSI C?
    Don't know if there's any difference)....


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 18, 2006
    #10
  11. Martin Jørgensen said:

    > jacob navia wrote:
    > -snip-
    >
    >> Standard C has several functions for this:
    >> 1) isfinite: returns true if its argument is finite
    >> 2) isinf: returns true if its argument is infinite
    >> 3) isnormal: returns true if its argument is normal
    >> 4) fpclassify returns the type of its argument.
    >>
    >> See the documentation of your compiler system.

    >
    > Ok.
    >
    >> P.S. This will work in standard C, not in Visual Studio.

    >
    > Is visual studio 2005 not standard C?


    Yes and no. VStudio conforms to ISO/IEC 9899:1990 (when you "disable
    Microsoft extensions" in the project settings), modulo some trivial and
    much-unused dark corners of the language. (Never come across these myself
    AFAICR, but people here in clc have occasionally waxed lyrical on the
    subject.)

    But it doesn't conform to ISO/IEC 9899:1999, which is what you'd need if you
    wanted to use Jacob Navia's suggestions. Having said that, almost no C
    compilers conform to that later spec - and so, even if VStudio did give you
    access to them, your code would still not be portable.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, May 18, 2006
    #11
  12. Richard Heathfield wrote:
    > Martin Jørgensen said:

    -snip-

    >>Is visual studio 2005 not standard C?

    >
    >
    > Yes and no. VStudio conforms to ISO/IEC 9899:1990 (when you "disable
    > Microsoft extensions" in the project settings), modulo some trivial and


    Exactly! That is what I did (disabled those stupid extensions).

    > much-unused dark corners of the language. (Never come across these myself
    > AFAICR, but people here in clc have occasionally waxed lyrical on the
    > subject.)
    >
    > But it doesn't conform to ISO/IEC 9899:1999, which is what you'd need if you
    > wanted to use Jacob Navia's suggestions. Having said that, almost no C
    > compilers conform to that later spec - and so, even if VStudio did give you
    > access to them, your code would still not be portable.


    isinf and isfinite looks to me like they also exists under unix, so
    doesn't that mean it would probably be portable?


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 18, 2006
    #12
  13. Martin Jørgensen said:

    > isinf and isfinite looks to me like they also exists under unix, so
    > doesn't that mean it would probably be portable?


    That depends entirely on your definition of "portable". :)

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, May 19, 2006
    #13
  14. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    jacob navia Guest

    Martin Jørgensen a écrit :
    > Richard Heathfield wrote:
    >
    >> Martin Jørgensen said:

    >
    > -snip-
    >
    >>> Is visual studio 2005 not standard C?

    >>
    >>
    >>
    >> Yes and no. VStudio conforms to ISO/IEC 9899:1990 (when you "disable
    >> Microsoft extensions" in the project settings), modulo some trivial and

    >
    >
    > Exactly! That is what I did (disabled those stupid extensions).
    >
    >> much-unused dark corners of the language. (Never come across these
    >> myself AFAICR, but people here in clc have occasionally waxed lyrical
    >> on the subject.)
    >>
    >> But it doesn't conform to ISO/IEC 9899:1999, which is what you'd need
    >> if you wanted to use Jacob Navia's suggestions. Having said that,
    >> almost no C compilers conform to that later spec - and so, even if
    >> VStudio did give you access to them, your code would still not be
    >> portable.

    >
    >
    > isinf and isfinite looks to me like they also exists under unix, so
    > doesn't that mean it would probably be portable?
    >
    >
    > Best regards / Med venlig hilsen
    > Martin Jørgensen
    >


    Visual studio conforms to the obsolete C standard of 1989.
    It has:
    isnan(double)
    isnanf(float)
    finitef(float)
    finite(double)

    Those functions can solve your problem too.
     
    jacob navia, May 19, 2006
    #14
  15. jacob navia <> writes:
    [...]
    > Visual studio conforms to the obsolete C standard of 1989.
    > It has:
    > isnan(double)
    > isnanf(float)
    > finitef(float)
    > finite(double)
    >
    > Those functions can solve your problem too.


    To be clear, the C89/C90 standard doesn't define those functions.
    (I won't comment on whether the C89/C90 standard is "obsolete".)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, May 19, 2006
    #15
  16. jacob navia said:

    > Visual studio conforms to the obsolete C standard of 1989.


    The 1989 Standard is far from obsolete. It is still the current de facto
    Standard, and will remain so until C99 is widely implemented. That day
    appears to be some way off - the GNU people have shied away from full
    conformance to C99, and Microsoft have ignored it completely.

    The C Standard is of no value unless it enables us to write portable code.
    C99 features are, quite simply, not even remotely as portable as C89
    features.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, May 19, 2006
    #16
  17. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    jacob navia Guest

    Richard Heathfield a écrit :
    > jacob navia said:
    >
    >
    >>Visual studio conforms to the obsolete C standard of 1989.

    >
    >
    > The 1989 Standard is far from obsolete. It is still the current de facto
    > Standard, and will remain so until C99 is widely implemented. That day
    > appears to be some way off - the GNU people have shied away from full
    > conformance to C99,


    The issues with gcc are VERY minor. It is a good C99 implementation, and
    can be used without any problems.

    and Microsoft have ignored it completely.

    Yes

    >
    > The C Standard is of no value unless it enables us to write portable code.


    This is your opinion. Your are entitled to it Mr Heathfield, but it is
    not mine anyway. There are people that will stay in the past, longing
    for the lost "golden times"...

    "Portability" for you means "taking the worst features of each
    implementation".

    There are C99 compilers under windows, and under Unix.
     
    jacob navia, May 19, 2006
    #17
  18. jacob navia said:

    > There are C99 compilers under windows, and under Unix.


    ROTFL! Well, that's all right then!

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, May 19, 2006
    #18
  19. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    jacob navia Guest

    Richard Heathfield a écrit :
    > jacob navia said:
    >
    >
    >>There are C99 compilers under windows, and under Unix.

    >
    >
    > ROTFL! Well, that's all right then!
    >


    Those are the operating systems mentioned in the original poster's
    message.

    You speak about "portability", as it was necessary for every piece of
    code to be potentially portable to all possible machines. This is mostly
    never the case. Many people do not care at all if their code can run
    without modifications at some embedded system with a 15 year old
    compiler you see?

    Some code running with visual studio or under a Mac OSx or similar
    will make so many hidden assumptions about RAM size, disk space, etc etc
    that it will NEVER run in the "System X" running in the toaster
    with 16k of ram.

    So What?
     
    jacob navia, May 19, 2006
    #19
  20. jacob navia said:

    > Richard Heathfield a écrit :
    >> jacob navia said:
    >>
    >>
    >>>There are C99 compilers under windows, and under Unix.

    >>
    >>
    >> ROTFL! Well, that's all right then!
    >>

    >
    > Those are the operating systems mentioned in the original poster's
    > message.


    He also mentioned the Mac.

    > You speak about "portability", as it was necessary for every piece of
    > code to be potentially portable to all possible machines.


    The general assumption in comp.lang.c is that the code is targeted at a
    hosted implementation of unknown provenance (unless it is specifically
    mentioned that a freestanding implementation is targeted). If the platform
    matters, well, there are other newsgroups where such discussions can be
    held.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, May 19, 2006
    #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. Hans
    Replies:
    3
    Views:
    2,509
    Ryan Stewart
    May 16, 2004
  2. Jon Wilson

    NaN and inf literal constants g++

    Jon Wilson, Dec 31, 2004, in forum: C++
    Replies:
    3
    Views:
    10,693
    Jon Wilson
    Dec 31, 2004
  3. zl2k
    Replies:
    10
    Views:
    1,194
  4. Joshua J. Kugler
    Replies:
    4
    Views:
    454
    Grant Edwards
    Sep 21, 2007
  5. ardi
    Replies:
    14
    Views:
    232
    Tim Prince
    Jan 5, 2014
Loading...

Share This Page