# checking double for Inf or NaN - how?

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

1. ### =?ISO-8859-1?Q?Martin_J=F8rgensen?=Guest

Hi,

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

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

Local uouble = 2 ' also works for floats

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

Print
Print

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

Function isfinite( xouble ) ' 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

2. ### =?ISO-8859-1?Q?Martin_J=F8rgensen?=Guest

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

....
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

3. ### Joe SmithGuest

"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 uouble = 2 ' also works for floats
>
> For Local n = 1 To 12
> Print isfinite(u) + " " + u
> u :* u
> Next
>
> Print
> Print
>
> u = u - u
> Print isfinite(u) + " " + u
>
>
> Function isfinite( xouble ) ' 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
4. ### =?ISO-8859-1?Q?Martin_J=F8rgensen?=Guest

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
5. ### bertGuest

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
>
> ...
> 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
6. ### peteGuest

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
>
> ...
> 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
7. ### =?ISO-8859-1?Q?Martin_J=F8rgensen?=Guest

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
>>
>>...
>> 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
8. ### =?ISO-8859-1?Q?Martin_J=F8rgensen?=Guest

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
>>
>>...
>> 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
9. ### jacob naviaGuest

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 uouble = 2 ' also works for floats
>
> For Local n = 1 To 12
> Print isfinite(u) + " " + u
> u :* u
> Next
>
> Print
> Print
>
> u = u - u
> Print isfinite(u) + " " + u
>
>
> Function isfinite( xouble ) ' 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
10. ### =?ISO-8859-1?Q?Martin_J=F8rgensen?=Guest

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
11. ### Richard HeathfieldGuest

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

--
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
12. ### =?ISO-8859-1?Q?Martin_J=F8rgensen?=Guest

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

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
13. ### Richard HeathfieldGuest

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
14. ### jacob naviaGuest

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
>> 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
15. ### Keith ThompsonGuest

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
16. ### Richard HeathfieldGuest

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
17. ### jacob naviaGuest

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
18. ### Richard HeathfieldGuest

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
19. ### jacob naviaGuest

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
20. ### Richard HeathfieldGuest

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