xref: /illumos-gate/usr/src/head/nan.h (revision 5e989a96186a37eb528fb7bb4d28a150874ec799)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1988 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 /*
27  * Copyright (c) 1996, by Sun Microsystems, Inc.
28  * All Rights Reserved
29  */
30 
31 #ifndef _NAN_H
32 #define	_NAN_H
33 
34 #pragma ident	"%Z%%M%	%I%	%E% SMI"
35 
36 /*
37  * Handling of Not_a_Number's (only in IEEE floating-point standard)
38  */
39 
40 #include <sys/isa_defs.h>
41 #include <values.h>
42 
43 #ifdef	__cplusplus
44 extern "C" {
45 #endif
46 
47 #if defined(_IEEE_754)
48 /*
49  * Structure order is endian dependent.  Only the common variants of
50  * big and little endian are supported.
51  */
52 
53 #if defined(_BIG_ENDIAN)
54 
55 typedef union
56 {
57 	struct
58 	{
59 		unsigned sign		: 1;
60 		unsigned exponent	:11;
61 		unsigned bits		:20;
62 		unsigned fraction_low	:32;
63 	} inf_parts;
64 	struct
65 	{
66 		unsigned sign		: 1;
67 		unsigned exponent	:11;
68 		unsigned qnan_bit	: 1;
69 		unsigned bits		:19;
70 		unsigned fraction_low	:32;
71 	} nan_parts;
72 	double d;
73 
74 } dnan;
75 
76 #else	/* Must be _LITTLE_ENDIAN */
77 
78 typedef union
79 {
80 	struct {
81 		unsigned fraction_low	:32;
82 		unsigned bits		:20;
83 		unsigned exponent	:11;
84 		unsigned sign		: 1;
85 	} inf_parts;
86 	struct {
87 		unsigned fraction_low	:32;
88 		unsigned bits		:19;
89 		unsigned qnan_bit	: 1;
90 		unsigned exponent	:11;
91 		unsigned sign		: 1;
92 	} nan_parts;
93 	double d;
94 } dnan;
95 
96 #endif	/* Endian based selection */
97 
98 /*
99  * IsNANorINF checks that exponent of double == 2047
100  * i.e. that number is a NaN or an infinity
101  */
102 #define	IsNANorINF(X)  (((dnan *)&(X))->nan_parts.exponent == 0x7ff)
103 
104 /*
105  * IsINF must be used after IsNANorINF has checked the exponent
106  */
107 #define	IsINF(X)	(((dnan *)&(X))->inf_parts.bits == 0 && \
108 			    ((dnan *)&(X))->inf_parts.fraction_low == 0)
109 
110 /*
111  * IsPosNAN and IsNegNAN can be used to check the sign of infinities too
112  */
113 #define	IsPosNAN(X)	(((dnan *)&(X))->nan_parts.sign == 0)
114 
115 #define	IsNegNAN(X)	(((dnan *)&(X))->nan_parts.sign == 1)
116 
117 /*
118  * GETNaNPC gets the leftmost 32 bits of the fraction part
119  */
120 #define	GETNaNPC(dval)	(((dnan *)&(dval))->inf_parts.bits << 12 | \
121 			    ((dnan *)&(dval))->nan_parts.fraction_low >> 20)
122 
123 #if defined(__STDC__)
124 #define	KILLFPE()	(void) _kill(_getpid(), 8)
125 #else
126 #define	KILLFPE()	(void) kill(getpid(), 8)
127 #endif
128 #define	NaN(X)		(((dnan *)&(X))->nan_parts.exponent == 0x7ff)
129 #define	KILLNaN(X)	if (NaN(X)) KILLFPE()
130 
131 #else	/* defined(_IEEE_754) */
132 /* #error is strictly ansi-C, but works as well as anything for K&R systems. */
133 #error ISA not supported
134 #endif	/* defined(_IEEE_754) */
135 
136 #ifdef	__cplusplus
137 }
138 #endif
139 
140 #endif	/* _NAN_H */
141