Not a number problem

Discussion in 'C Programming' started by istillshine@gmail.com, Apr 4, 2008.

  1. Guest

    In my code I used NAN and isnan(x). I found they were convenient to
    use. I also noticed that
    older C standard does not support NAN and isnan(x).

    When I compiled my program using:

    gcc -Wall -c

    it was fine.


    But when I compiled my program using:

    gcc -Wall -ansi -pedantic -c

    it reported some errors, reporting NAN and isnan(x) not supported.

    I knew the options -ansi and -pedantic make things conform to the
    older C standard (C90?).

    My question are:

    1. Is it fine to compile my program using "gcc -Wall -c" instead of
    using the more conservative "gcc -Wall -ansi -pedantic -c"?

    2. Dose including NAN and isnan(x) hurt the portability of a program,
    given high version of gcc is available in both Linux and Windows
    (MinGW)?
    , Apr 4, 2008
    #1
    1. Advertising

  2. On 4 Apr, 15:43, wrote:

    > In my code I used NAN and isnan(x).  I found they were convenient to
    > use.  I also noticed that
    > older C standard does not support NAN and isnan(x).


    only C99 supports IEEE floating point, and even then
    only if a particular macro is defined (

    > When I compiled my program using:
    >
    > gcc -Wall -c
    >
    > it was fine.
    >
    > But when I compiled my program using:
    >
    > gcc -Wall -ansi -pedantic -c
    >
    > it reported some errors, reporting NAN and isnan(x) not supported.
    >
    > I knew the options -ansi and -pedantic make things conform to the
    > older C standard (C90?).
    >
    > My question are:
    >
    > 1. Is it fine to compile my program using  "gcc -Wall -c" instead of
    > using the more conservative "gcc -Wall -ansi -pedantic -c"?
    >
    > 2. Dose including NAN and isnan(x) hurt the portability of a program,
    > given high version of gcc is available in both Linux and Windows
    > (MinGW)?
    Nick Keighley, Apr 4, 2008
    #2
    1. Advertising

  3. oops! last post sent in error

    On 4 Apr, 15:43, wrote:

    > In my code I used NAN and isnan(x).  I found they were convenient to
    > use.  I also noticed that
    > older C standard does not support NAN and isnan(x).


    as I said... only c99 offers IEEE support and even then it
    is optional.


    > When I compiled my program using:
    >
    > gcc -Wall -c
    >
    > it was fine.
    >
    > But when I compiled my program using:
    >
    > gcc -Wall -ansi -pedantic -c
    >
    > it reported some errors, reporting NAN and isnan(x) not supported.


    as they aren't part of the standard


    > I knew the options -ansi and -pedantic make things conform to the
    > older C standard (C90?).


    probably c90

    > My question are:
    >
    > 1. Is it fine to compile my program using  "gcc -Wall -c" instead of
    > using the more conservative "gcc -Wall -ansi -pedantic -c"?


    only you can answer this. What is more important to you, IEEE
    support or maximal portability?


    > 2. Dose including NAN and isnan(x) hurt the portability of a program,


    yes

    > given high version of gcc is available in both Linux and Windows
    > (MinGW)?


    where is your software likely to run? If you going to
    do lots of floating point you may decide to only support
    systems that have IEEE support (a lot these days).

    You might try putting gcc into its (almost) C99 mode.

    The world is NOT confined to Linux and Windows


    --
    Nick Keighley
    Nick Keighley, Apr 4, 2008
    #3
  4. Guest

    On Apr 4, 5:55 pm, Nick Keighley <>
    wrote:
    > On 4 Apr, 15:43, wrote:
    >
    > > In my code I used NAN and isnan(x). I found they were convenient to
    > > use. I also noticed that
    > > older C standard does not support NAN and isnan(x).

    >
    > only C99 supports IEEE floating point, and even then
    > only if a particular macro is defined (

    Hmm.. something went wrong here? :)
    The macro is __STDC_IEC_559__
    <snip>
    , Apr 4, 2008
    #4
  5. Nick Keighley wrote:
    > oops! last post sent in error
    >
    > On 4 Apr, 15:43, wrote:
    >
    >> In my code I used NAN and isnan(x). I found they were convenient to
    >> use. I also noticed that
    >> older C standard does not support NAN and isnan(x).

    >
    > as I said... only c99 offers IEEE support and even then it
    > is optional.


    This is true but misleading. C99 does only offer optional IEEE support,
    but the isnan() macro is not part of the IEEE extension.

    See n1256 7.12.3.4 - isnan() is defined in math.h in all C99
    implementations. (more below)

    >> But when I compiled my program using:
    >>
    >> gcc -Wall -ansi -pedantic -c
    >>
    >> it reported some errors, reporting NAN and isnan(x) not supported.

    >
    > as they aren't part of the standard


    NaN values and the isnan() macro are part of the standard. To be
    precise, the standard allows but does not require NaNs to exist. If NaNs
    don't exist the isnan() macro must still be provided and always returns
    zero. The NAN macro is defined if and only if quiet NaN values are
    supported by the float type.

    >> I knew the options -ansi and -pedantic make things conform to the
    >> older C standard (C90?).

    >
    > probably c90


    Yes, -ansi corresponds to C90. (AFAIK it is equivalent to -std=c90)

    >> My question are:
    >>
    >> 1. Is it fine to compile my program using "gcc -Wall -c" instead of
    >> using the more conservative "gcc -Wall -ansi -pedantic -c"?

    >
    > only you can answer this. What is more important to you, IEEE
    > support or maximal portability?


    Again, there are more NaN-supporting systems than just IEEE.

    >> 2. Dose including NAN and isnan(x) hurt the portability of a program,

    >
    > yes


    Probably.
    Philip Potter, Apr 4, 2008
    #5
  6. Guest

    Then I wonder how people deal with NAN or INFINITY numbers in a
    portable manner? I guess this situation arises frequently in
    developing numerical softwares. In my program, I need to do something
    like the following:


    while (1) {
    ...
    x = some expression; /* may cause problem */
    if (x is neither NAN nor INFINITY) { /* make sure x is a useful
    number */
    break;
    } else {
    /* deal with the problem */
    }
    }



    On Apr 4, 11:02 am, Nick Keighley <>
    wrote:
    > oops! last post sent in error
    >
    > On 4 Apr, 15:43, wrote:
    >
    > > In my code I used NAN and isnan(x). I found they were convenient to
    > > use. I also noticed that
    > > older C standard does not support NAN and isnan(x).

    >
    > as I said... only c99 offers IEEE support and even then it
    > is optional.
    >
    > > When I compiled my program using:

    >
    > > gcc -Wall -c

    >
    > > it was fine.

    >
    > > But when I compiled my program using:

    >
    > > gcc -Wall -ansi -pedantic -c

    >
    > > it reported some errors, reporting NAN and isnan(x) not supported.

    >
    > as they aren't part of the standard
    >
    > > I knew the options -ansi and -pedantic make things conform to the
    > > older C standard (C90?).

    >
    > probably c90
    >
    > > My question are:

    >
    > > 1. Is it fine to compile my program using "gcc -Wall -c" instead of
    > > using the more conservative "gcc -Wall -ansi -pedantic -c"?

    >
    > only you can answer this. What is more important to you, IEEE
    > support or maximal portability?
    >
    > > 2. Dose including NAN and isnan(x) hurt the portability of a program,

    >
    > yes
    >
    > > given high version of gcc is available in both Linux and Windows
    > > (MinGW)?

    >
    > where is your software likely to run? If you going to
    > do lots of floating point you may decide to only support
    > systems that have IEEE support (a lot these days).
    >
    > You might try putting gcc into its (almost) C99 mode.
    >
    > The world is NOT confined to Linux and Windows
    >
    > --
    > Nick Keighley
    , Apr 4, 2008
    #6
  7. In article <>,
    <> wrote:
    >Then I wonder how people deal with NAN or INFINITY numbers in a
    >portable manner? I guess this situation arises frequently in
    >developing numerical softwares.


    NaN and Infinity do not occur in all floating point systems.
    For example it was not uncommon for single precision floating point
    numbers to be in some native format that used the entire value
    space instead of reserving some of the potential value space as
    special values such as infinity or the various types of NaN.

    Thus, "dealing with NaN or infinity numbers in a portable manner"
    is dubious -- unless, that is, you choose to restrict your
    portability to systems that have defined support for them built in.


    A classic test for a NaN, by the way, is

    (!(x==x) && !(x!=x))

    That is, a NaN does not compare equal to itself, and also does not
    compare -not equal- to itself. And hope that the compiler doesn't
    optimize the test away thinking that "of course x==x" . A compiler
    that doesn't know that NaN's exist might make that mistake, so code
    carefully.


    If you are working with NaN and infinity, then chances are that you
    are also concerned with rounding modes; the manipulation of rounding
    modes is usually fairly system-specific before C99 (and
    from what I remember, C99 does not capture the full flavour of
    rounding modes.)
    --
    "Walter exemplified class." -- Paul Tagliabue
    Walter Roberson, Apr 4, 2008
    #7
  8. jacob navia Guest

    wrote:
    > Then I wonder how people deal with NAN or INFINITY numbers in a
    > portable manner? I guess this situation arises frequently in
    > developing numerical softwares. In my program, I need to do something
    > like the following:
    >
    >
    > while (1) {
    > ...
    > x = some expression; /* may cause problem */
    > if (x is neither NAN nor INFINITY) { /* make sure x is a useful
    > number */
    > break;
    > } else {
    > /* deal with the problem */
    > }
    > }
    >



    Just use isnan() and be done with it. It is standard C.
    And if you find a compiler that doesn't support isnan()
    throw it away and get a better one.

    P.S.
    I think

    int isnan(double x)
    {
    if (x != x)
    return 1;
    return 0;
    }


    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Apr 4, 2008
    #8
  9. In article <ft693m$88u$>, jacob navia <> wrote:

    >P.S.
    >I think


    >int isnan(double x)
    >{
    > if (x != x)
    > return 1;
    > return 0;
    >}


    Though what happens if x is a signalling NaN? Signalling NaNs trigger
    when their value is used. Just testing isnan(x) is not a use of the
    value (it's test of the properties), but x != x would be a use of
    the value and so would (if I understand correctly) trigger the signal.

    --
    "It's a hard life sometimes and the biggest temptation is to let
    how hard it is be an excuse to weaken." -- Walter Dean Myers
    Walter Roberson, Apr 4, 2008
    #9
  10. On Apr 4, 10:35 pm, -cnrc.gc.ca (Walter Roberson)
    wrote:

    > A classic test for a NaN, by the way, is
    >
    >   (!(x==x) && !(x!=x))
    >
    > That is, a NaN does not compare equal to itself, and also does not
    > compare -not equal- to itself.


    NaN _always_ compares not equal to itself, that is x != x is _always_
    true for NaNs. And (x != y) will _always_ give the same result as ! (x
    == y), even with one or more NaNs and/or Infinities involved.
    christian.bau, Apr 4, 2008
    #10
  11. jacob navia Guest

    Walter Roberson wrote:
    > In article <ft693m$88u$>, jacob navia <> wrote:
    >
    >> P.S.
    >> I think

    >
    >> int isnan(double x)
    >> {
    >> if (x != x)
    >> return 1;
    >> return 0;
    >> }

    >
    > Though what happens if x is a signalling NaN? Signalling NaNs trigger
    > when their value is used. Just testing isnan(x) is not a use of the
    > value (it's test of the properties), but x != x would be a use of
    > the value and so would (if I understand correctly) trigger the signal.
    >


    The signal would be triggered anyway. It is up to you to
    hide that signal using the fesetenv() (if you use C99) or
    whatever. In ANY case, if you have a signaling NAN as a
    result of a computation and the processor has that signal unmasked
    your program will crash anyway.

    I do not see the point of your objection.


    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Apr 4, 2008
    #11
  12. -cnrc.gc.ca (Walter Roberson) writes:
    > In article <ft693m$88u$>, jacob navia <> wrote:
    >
    >>P.S.
    >>I think

    >
    >>int isnan(double x)
    >>{
    >> if (x != x)
    >> return 1;
    >> return 0;
    >>}


    Why not this?

    int isnan(double x)
    {
    return x != x;
    }

    (Just a minor style point.)

    (Either way, the equivalent of isnan() is easy enough to implement
    even in C90 that there's no point in rejecting a non-C99 compiler just
    for this reason.)

    > Though what happens if x is a signalling NaN? Signalling NaNs trigger
    > when their value is used. Just testing isnan(x) is not a use of the
    > value (it's test of the properties), but x != x would be a use of
    > the value and so would (if I understand correctly) trigger the signal.


    C99 explicitly doesn't define the behavior of signaling NaNs, even in
    the optional Annex F (IEC 60559 floating-point arithmetic). The
    isnan() function presumably tests for a quiet NaN. As jacob points
    out, invoking ``isnan(x)'' if x is a signalling NaN has to evalute x
    first, which could result in a trap.

    In effect, signalling NaNs are just trap representations.

    Note that the language could have provided, and an implementation can
    provide, a function that tests for signalling NaNs:

    int is_signalling_nan(double *x);

    It could, for example, convert the double* argument to unsigned char*
    and examine the representation, using system-specific knowledge of
    what a signalling NaN looks like. As long as it doesn't access the
    value *as floating-point*, it won't invoke UB. (Either this would
    have to be a macro, probably using ``sizeof *x'' to determine what
    type it points to, or there would have to be versions for float,
    double, and long double.)

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 5, 2008
    #12
  13. Guest

    I got the following message when I compiled my program using "gcc -
    Wall -c -ansi -pedantic"

    tr.c:1246: warning: implicit declaration of function `isnan'

    min.o(.text+0x36d):minimize.c: undefined reference to `isinf'

    It seemed isnan() is not there by default. And, how to determine if a
    number is infinite (negative or positive)?

    Will the following function work?

    int isinf(double x)
    {
    return x == -DBL_MAX || x == DBL_MAX;
    }


    On Apr 4, 6:12 pm, jacob navia <> wrote:
    > wrote:
    > > Then I wonder how people deal with NAN or INFINITY numbers in a
    > > portable manner? I guess this situation arises frequently in
    > > developing numerical softwares. In my program, I need to do something
    > > like the following:

    >
    > > while (1) {
    > > ...
    > > x = some expression; /* may cause problem */
    > > if (x is neither NAN nor INFINITY) { /* make sure x is a useful
    > > number */
    > > break;
    > > } else {
    > > /* deal with the problem */
    > > }
    > > }

    >
    > Just use isnan() and be done with it. It is standard C.
    > And if you find a compiler that doesn't support isnan()
    > throw it away and get a better one.
    >
    > P.S.
    > I think
    >
    > int isnan(double x)
    > {
    > if (x != x)
    > return 1;
    > return 0;
    >
    > }
    >
    > --
    > jacob navia
    > jacob at jacob point remcomp point fr
    > logiciels/informatiquehttp://www.cs.virginia.edu/~lcc-win32
    , Apr 5, 2008
    #13
  14. Guest

    I just tried the isinf() function I wrote previously, it did not
    work. However, I found somewhere in clc an alternative:

    static int isinf(double x)
    {
    return (x == x) && (x != 0) && (x + 1 == x);
    }

    And tested it using isinf(log(0) and isinf(1.0/0.0). It seemed
    working.


    On Apr 5, 12:18 am, wrote:
    > I got the following message when I compiled my program using "gcc -
    > Wall -c -ansi -pedantic"
    >
    > tr.c:1246: warning: implicit declaration of function `isnan'
    >
    > min.o(.text+0x36d):minimize.c: undefined reference to `isinf'
    >
    > It seemed isnan() is not there by default. And, how to determine if a
    > number is infinite (negative or positive)?
    >
    > Will the following function work?
    >
    > int isinf(double x)
    > {
    > return x == -DBL_MAX || x == DBL_MAX;
    >
    > }
    >
    > On Apr 4, 6:12 pm, jacob navia <> wrote:
    >
    > > wrote:
    > > > Then I wonder how people deal with NAN or INFINITY numbers in a
    > > > portable manner? I guess this situation arises frequently in
    > > > developing numerical softwares. In my program, I need to do something
    > > > like the following:

    >
    > > > while (1) {
    > > > ...
    > > > x = some expression; /* may cause problem */
    > > > if (x is neither NAN nor INFINITY) { /* make sure x is a useful
    > > > number */
    > > > break;
    > > > } else {
    > > > /* deal with the problem */
    > > > }
    > > > }

    >
    > > Just use isnan() and be done with it. It is standard C.
    > > And if you find a compiler that doesn't support isnan()
    > > throw it away and get a better one.
    > > > P.S.



    > > I think

    >
    > > int isnan(double x)
    > > {
    > > if (x != x)
    > > return 1;
    > > return 0;

    >
    > > }

    >
    > > --
    > > jacob navia
    > > jacob at jacob point remcomp point fr
    > > logiciels/informatiquehttp://www.cs.virginia.edu/~lcc-win32
    , Apr 5, 2008
    #14
  15. In article <05adnaK7WogAh2ranZ2dnUVZ_qiinZ2d@internetamerica>,
    Gordon Burditt <> wrote:

    >> return (x == x) && (x != 0) && (x + 1 == x);



    >I have serious doubts that this will work correctly for large but
    >non-infinite numbers. For example, consider 1.0e+300. This fits
    >in an IEEE double. It compares equal to itself. It does not compare
    >equal to zero. And 1.0e+300 is going to compare equal to 1.0e+300
    >+ 1 because you don't have nearly enough mantissa bits in an IEEE
    >double to distinguish the two.


    Perhaps x == x/2 would work better. You would need the x != 0 in that
    case.

    -- Richard
    --
    :wq
    Richard Tobin, Apr 5, 2008
    #15
  16. Guest

    It is very good for me to learn this point. Thanks.

    > And 1.0e+300 is going to compare equal to 1.0e+300
    > + 1 because you don't have nearly enough mantissa bits in an IEEE
    > double to distinguish the two.
    , Apr 5, 2008
    #16
  17. Guest

    Collecting ideas from you, I wrote a header file to handle the isnan
    and isinf problem.

    #ifndef _NAN_H
    #define _NAN_H

    #ifndef isnan
    #define isnan(x) ((x) != (x))
    #endif

    #ifndef isinf
    #define isinf(x) (((x) == (x)) && ((x) != 0) && ((x)/2 == (x)))
    #endif

    #endif /* _NAN_H */

    Will the above work in most cases? I tried log(0), 1.0/0.0, and 1.0e
    +300. They seemed to work fine.


    On Apr 5, 5:45 am, (Richard Tobin) wrote:
    > In article <05adnaK7WogAh2ranZ2dnUVZ_qiinZ2d@internetamerica>,
    >
    > Gordon Burditt <> wrote:
    > >> return (x == x) && (x != 0) && (x + 1 == x);

    > >I have serious doubts that this will work correctly for large but
    > >non-infinite numbers. For example, consider 1.0e+300. This fits
    > >in an IEEE double. It compares equal to itself. It does not compare
    > >equal to zero. And 1.0e+300 is going to compare equal to 1.0e+300
    > >+ 1 because you don't have nearly enough mantissa bits in an IEEE
    > >double to distinguish the two.

    >
    > Perhaps x == x/2 would work better. You would need the x != 0 in that
    > case.
    >
    > -- Richard
    > --
    > :wq
    , Apr 5, 2008
    #17
  18. writes:
    > Collecting ideas from you, I wrote a header file to handle the isnan
    > and isinf problem.
    >
    > #ifndef _NAN_H
    > #define _NAN_H
    >
    > #ifndef isnan
    > #define isnan(x) ((x) != (x))
    > #endif
    >
    > #ifndef isinf
    > #define isinf(x) (((x) == (x)) && ((x) != 0) && ((x)/2 == (x)))
    > #endif
    >
    > #endif /* _NAN_H */
    >
    > Will the above work in most cases? I tried log(0), 1.0/0.0, and 1.0e
    > +300. They seemed to work fine.


    I don't know of any problems, but as Gordon Burditt pointed out, you
    need to check for corner cases. However, I'd suggest picking
    different names, since "isnan" and "isinf" are defined as macro names
    in <math.h> in C99. Also, the identifier "_NAN_H" is reserved to the
    implementation. In general, it's best to avoid identifiers that start
    with underscores.

    If you're going to be posting here, you should learn some of the
    guidelines. Please don't top-post; your response goes after, or
    interspersed with, the text you're responding to. See:
    http://www.caliburn.nl/topposting.html
    http://www.cpax.org.uk/prg/writings/topposting.php

    Trim quoted material down to what's necessary for your response to
    make sense. It's usually not necessary to quote the entire previous
    article. In particular, don't quote signatures (the stuff following
    the "-- " line) unless you're actually commenting on them.

    And please don't delete attribution lines (you didn't do so this time,
    but you did in another article in this thread). Attribution lines are
    the lines of the form "So-and-so write:"; they make it easier to
    follow the discussion. (Gordon Burditt sets a bad example, though
    he's been posting here long enough to know better.)

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 5, 2008
    #18
    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. makok
    Replies:
    1
    Views:
    6,746
    Anders Hellerup Madsen
    Feb 23, 2004
  2. hari
    Replies:
    6
    Views:
    6,899
    hamilton
    May 2, 2004
  3. mayur
    Replies:
    2
    Views:
    1,000
    Natty Gur
    Jul 2, 2004
  4. Replies:
    5
    Views:
    508
    Pete Becker
    May 21, 2005
  5. Hako
    Replies:
    13
    Views:
    38,786
    Ron Adam
    Nov 10, 2005
Loading...

Share This Page