/*	Copyright (c) 1984, 1986, 1987, 1988 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

#ident	"@(#)head:nan.h	1.13"

/* Handling of Not_a_Number's (only in IEEE floating-point standard) */
#if _IEEE
#if !i286 && !i386
typedef union 
{
         struct	
	 {
	    unsigned sign     : 1;
	    unsigned exponent :11;
            unsigned bits:20;
	    unsigned fraction_low:32;
         } inf_parts;
	 struct 
	 {
	    unsigned sign     : 1;
            unsigned exponent :11;
	    unsigned qnan_bit : 1;
	    unsigned bits     :19;
	    unsigned fraction_low: 32;
         } nan_parts;
         double d;

} dnan; 
#endif

#if i386
typedef union 
{
	struct {
		unsigned fraction_low:32;
		unsigned bits:20;
		unsigned exponent :11;
		unsigned sign     : 1;
	} inf_parts;
	struct {
		unsigned fraction_low: 32;
		unsigned bits     :19;
		unsigned qnan_bit : 1;
		unsigned exponent :11;
		unsigned sign     : 1;
	} nan_parts;
	double d;
} dnan;
#endif

#if i286
   /*
    * i286 has 16 bit words and cannot address the fields that
    * 32-bit machines can.
    */
typedef union 
{
	struct	
	{
		unsigned long fraction_low;
		unsigned short bits2;
		unsigned bits1	 :4;
		unsigned exponent :11;
		unsigned sign	  : 1;
	} inf_parts;
	struct 
	{
		unsigned long fraction_low;
		unsigned short bits2;
		unsigned bits1	 : 3;
		unsigned qnan_bit : 1;
		unsigned exponent :11;
		unsigned sign	  : 1;
	} nan_parts;
	double d;
} dnan; 
#endif

	/* IsNANorINF checks that exponent of double == 2047 *
	 * i.e. that number is a NaN or an infinity	     */
	
#define IsNANorINF(X)  (((dnan *)&(X))->nan_parts.exponent == 0x7ff)

	/* IsINF must be used after IsNANorINF		*
 	 * has checked the exponent 			*/

#ifndef i286
#define IsINF(X)  (((dnan *)&(X))->inf_parts.bits == 0 &&  \
                    ((dnan *)&(X))->inf_parts.fraction_low == 0)
#else
#define IsINF(X)  (((dnan *)&(X))->inf_parts.bits1 == 0 &&  \
                   ((dnan *)&(X))->inf_parts.bits2 == 0 &&  \
                   ((dnan *)&(X))->inf_parts.fraction_low == 0)
#endif

	/* IsPosNAN and IsNegNAN can be used 		*
 	 * to check the sign of infinities too		*/

#define IsPosNAN(X)  (((dnan *)&(X))->nan_parts.sign == 0)

#define IsNegNAN(X)  (((dnan *)&(X))->nan_parts.sign == 1)

	/* GETNaNPC gets the leftmost 32 bits 		*	
	 * of the fraction part				*/

#ifndef i286
#define GETNaNPC(dval)   (((dnan *)&(dval))->inf_parts.bits << 12 | \
			  ((dnan *)&(dval))->nan_parts.fraction_low>> 20) 
#else
#define GETNaNPC(dval)   ((long) ((dnan *)&(dval))->inf_parts.bits1 << 28 | \
			  (long) ((dnan *)&(dval))->inf_parts.bits2 << 12 | \
			  ((dnan *)&(dval))->nan_parts.fraction_low>> 20) 
#endif


#define KILLFPE()       (void) kill(getpid(), 8)
#define NaN(X)  (((dnan *)&(X))->nan_parts.exponent == 0x7ff)
#define KILLNaN(X)      if (NaN(X)) KILLFPE()
#else

typedef double dnan;
#define IsINF(X)   0
#define IsPINF(X)  0
#define IsNegNAN(X)  0
#define IsPosNAN(X)  0
#define IsNAN(X)   0
#define GETNaNPC   0L

#define NaN(X)  0
#define KILLNaN(X)
#endif

