No subject

Fred Tydeman sun!uunet.UU.NET!ibmsupt!ibmpa!tydeman
Tue Aug 28 09:20:45 PDT 1990


Subject:  How much support for NaN in C for I/O conversions?
 
A question has come  up as to how much support do users  want, in C, for
NaN (Not-a-Number), that  IEEE-754 and IEEE-854 require.   This question
is in the area  for scanf, printf, strtod, and atof  and which string(s)
should be used.
 
Four possible levels of support are:
 
1) Treat all  NaNs, both  quiet and  signaling, the  same, and  as quiet
   NaNs.  Use  the string "NaN" as the representation.   Probably ignore
   the sign bit.   Case (upper, lower,  mixed) may matter.   This is the
   level of support now done by some implementations.  It does not allow
   a user  to input  a signaling NaN  via scanf, which  appears to  be a
   requirement  of IEEE-854  (section  5.6  Floating-Point <-->  Decimal
   String Conversion).
 
2) Differentiate quiet NaN from signaling NaN.  Treat all quiet NaNs the
   same.  Treat  all signaling NaNs the  same.  Probably honor  the sign
   bit.   Ignore case (allow  upper, lower,  and mixed).   Some possible
   string representations are:
 
                  Input               Output
   Quiet-NaN      NaN or NaNQ         NaN
   Signaling-NaN  NaNS                NaNS
 
   Quiet-NaN      NaN or NaNQ         NaNQ
   Signaling-NaN  NaNS                NaNS
 
   Quiet-NaN      NaNQ                NaNQ
   Signaling-NaN  NaN or NaNS         NaNS
 
   This appears to be the level of support that IEEE-854 wants.
 
3) Full support for all NaNs.  In addition to above, support a string
   representation that allows input and displays output of the general
   bit pattern that NaNs are allowed to have.
 
   A suggested general NaN syntax:
     NaN(n-char-sequence)
 
     n-char-sequence:
       SQ-bit SQ-value(opt)
 
     SQ-bit:
       S or Q
 
     SQ-value:
       "," integer-constant
 
   The syntax  of integer-constant is from  ANSI C section  3.1.3.2 that
   allows for  unsigned decimal or  octal or hexadecimal  constants with
   any number of digits.
 
   The semantics of the  general NaN will need some words  to the effect
   that  the value  is  a 22-bit  unsigned  integer  for floats,  51-bit
   unsigned integer for doubles, and a  ??-bit unsigned integer for long
   double (where ??   depends upon the implementation,  but is typically
   62).  That is, the type  of these integer-constants do not correspond
   to the int, long int, unsigned long int, ... of C.
 
   Some sample general NaNs are:
    -NaN(Q,0x3fffff)
    +NaN(S,017777777)
     NaN(Q,4194303)
     NaN(S)
     NaN(S,0x5555555555555)
 
   If this level were adopted, we would still allow shorthands for the
   common cases, as per level 2:  NaN, NaNS, and NaNQ.
 
4) Some other level of support as requested by the users or suggested by
   the NCEG (Numerical C Extensions Group).
 
Since a signaling NaN cannot be generated by any IEEE-754/854 operation,
there are two ways to create signaling NaNs.  One way involves unions of
ints  with  floats  or  array  of   ints  with  doubles  or  casts  from
pointers-to-ints   to    pointers-to-void   to    pointers-to-float   or
pointers-to-double.  This may run into problems of order of bytes within
words (big-endian versus  little-endian) as well as size of  ints.  This
probably is machine dependent and compiler dependent.
 
The other way is  to have scanf (or another member  of that family, such
as sscanf), read a string representation  of a signaling NaN and convert
it into the  internal bit pattern and  store it into the  variable whose
address was passed to scanf, eg,
       sscanf( "NaNS -NaNS", "%f %lf", &a_float, &a_double );
This should be a machine independent operation.  This argues for a short
standard string representation of signaling NaN.



More information about the Numeric-interest mailing list