[comp.sys.mac] Testing for NaN in Think C

hines@portia.Stanford.EDU (Melissa Hines) (03/27/90)

I've got a quick Think C question: How do you test for NaN (Not A Number) in
Think C?  It is very easy to generate NaN:
    float Nan;
    NaN = 0.0/0.0;
It is not as easy to test for it however.  For example, the following does not
work:
    float test,NaN;
    NaN = 0.0/0.0;
    if (test == NaN)
        ;
      else
        ; /* I always break to this loop, not the one above regardless of what
                I set test to. */
The following does work, but is pretty ugly:
    if((test/test != 1) && (test != 0))
        ; /* Here if NaN */
      else
        ; /* Here otherwise */
Is there a simpler/ more elegant way of doing this?  I think part of the
problem is that the IEEE have decreed that the result of any operation on
a NaN is a Nan.  Also, I think Think C may have more than one type of NaN. I
couldn't care less about the type, I just want to know if it is a NaN.

Thanks for your help!

Melissa Hines
Dept. of Chemistry
Stanford Univ.
Hines@Portia.Stanford.Edu
Hines@Cellbio.Stanford.Edu

nano%urbina@Sun.COM (Nano) (03/28/90)

Melissa Hines writes:

>    if((test/test != 1) && (test != 0))
>        ; /* Here if NaN */
>      else
>        ; /* Here otherwise */
>Is there a simpler/ more elegant way of doing this?  I think part of the
>problem is that the IEEE have decreed that the result of any operation on
>a NaN is a Nan.  Also, I think Think C may have more than one type of NaN. I
>couldn't care less about the type, I just want to know if it is a NaN.

There are quiet NaN's and signalling NaN's.  They differ by whether the
MSBit of the fraction part of the number is 1 or 0.  (Fraction as in IEEE
fraction).  You could always look at the actual representation of the
number and determine whether it's a NaN, but the simpler way would be
to compare the number to itself.  The IEEE spec defines a comparison involving
a NaN as "unordered", thus, if you compare test to itself, if it's 
a NaN, the comparison will fail:

	if (test != test)
		; /* Here if NaN */
	else
		; /* Here otherwise */

I haven't tried it, but it should work this way if everything is
IEEE compatible.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
Fernando A. Urbina              INTERNET:  nano@sun.com
                                       nano@mcimail.com
                                MCI:           408-0187

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

kam@dlogics.COM (Kevin Mitchell) (03/29/90)

To find if you have a NaN, use the SANE call ClassExtended.

NumClass ClassExtended(extended);

if (ClassExtended(num)==QNaN /* or SNaN */) ...


-- 
Kevin A. Mitchell                (312) 266-4485
Datalogics, Inc                  Internet: kam@dlogics.UUCP
441 W. Huron                     UUCP: ..!uunet!dlogics!kam
Chicago, IL  60610               FAX: (312) 266-4473