[comp.lang.c] NaN

shankar@hpclscu.HP.COM (Shankar Unni) (06/11/88)

NaN's are not a Unix feature, they're a feature of the IEEE floating point
standard. (The IEEE Standard for Binary Floating-Point Arithmetic,
ANSI/IEEE Std 754-1985, if you want me to be pedantic..).

The problem with defining a "NaN constant" is that there is a whole range of
bit patterns that fall into this "NaN" category, and even they fall into
two subcategories: Quiet and Signalling NaN's (according to whether or not they
generate floating-point traps when operated upon). Thus, it's kind of
difficult to do a thing like:

   if (f == NaN) { /* .. */ }

Also, it is hard (if not impossible) to come up with a way of representing
*any* NaN as a digit string or an expression in the C floating-point format.
How's about

   #define NaN (1.0 / 0.0)

? It looks kinda ugly.. Else, it might mean predefining it in the compiler
itself. What about different kinds of NaN's, then?

A good solution would be to add a few routines to libm.a, (or a new libIEEEf.a)
of the form:

  int isSNaNf (float f) { /* bit checking */ }
  int isQNaNf (float f) { /* bit checking */ }
  int isNaNf (float f) {return isQNaNf(f) || isSNaNf(f);}
  int isSNaNd (double f) { /* bit checking */ }
  int isQNaNd (double f) { /* bit checking */ }
  int isNaNd (double f) {return isQNaNd(f) || isSNaNd(f);}
  float SNaNf() { /* returns some Signalling NaN */ }
  ....

.. and, well, you get the idea.. Maybe also some stuff to examine the FP
status bits for conditions like overflow, inexact result, etc, or to arm
and disarm traps..

How about it?

Shankar.

ark@alice.UUCP (06/12/88)

In article <660011@hpclscu.HP.COM>, shankar@hpclscu.UUCP writes:
 
> Thus, it's kind of difficult to do a thing like:

>    if (f == NaN) { /* .. */ }

Not if traps are disabled.  NaN is not equal to anything, so you
can simply say

	if (f != f) { /* ... */ }

> How's about
 
>    #define NaN (1.0 / 0.0)
 
Nope.  1.0/0.0 is infinity, not NaN.  However, if appropriate traps
are disabled, 0.0/0.0 is a NaN.

> A good solution would be to add a few routines to libm.a

IEEE recommends specific routines, though I've forgotten what they are.
Of course, any such routines will only work on machines with IEEE
floating point (or equivalent).