xref: /illumos-gate/usr/src/head/nan.h (revision 5422785d352a2bb398daceab3d1898a8aa64d006)
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 2014 Garrett D'Amore <garrett@damore.org>
28  *
29  * Copyright (c) 1996, by Sun Microsystems, Inc.
30  * All Rights Reserved
31  */
32 
33 #ifndef _NAN_H
34 #define	_NAN_H
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 #define	KILLFPE()	(void) _kill(_getpid(), 8)
124 #define	NaN(X)		(((dnan *)&(X))->nan_parts.exponent == 0x7ff)
125 #define	KILLNaN(X)	if (NaN(X)) KILLFPE()
126 
127 #else	/* defined(_IEEE_754) */
128 /* #error is strictly ansi-C, but works as well as anything for K&R systems. */
129 #error ISA not supported
130 #endif	/* defined(_IEEE_754) */
131 
132 #ifdef	__cplusplus
133 }
134 #endif
135 
136 #endif	/* _NAN_H */
137