1 /* Copyright (C) 1992-2021 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #ifndef _IEEE754_H
19 
20 #define _IEEE754_H 1
21 
22 #ifndef _GL_GNULIB_HEADER
23 /* Ordinary glibc usage.  */
24 # include <features.h>
25 # include <endian.h>
26 #else
27 /* Gnulib usage.  */
28 # ifndef __BEGIN_DECLS
29 #  ifdef __cplusplus
30 #   define __BEGIN_DECLS	extern "C" {
31 #   define __END_DECLS		}
32 #  else
33 #   define __BEGIN_DECLS
34 #   define __END_DECLS
35 #  endif
36 # endif
37 # ifndef __FLOAT_WORD_ORDER
38 #  define __LITTLE_ENDIAN	1234
39 #  define __BIG_ENDIAN		4321
40 #  ifdef WORDS_BIGENDIAN
41 #   define __BYTE_ORDER __BIG_ENDIAN
42 #  else
43 #   define __BYTE_ORDER __LITTLE_ENDIAN
44 #  endif
45 #  define __FLOAT_WORD_ORDER __BYTE_ORDER
46 # endif
47 #endif
48 
49 __BEGIN_DECLS
50 
51 union ieee754_float
52   {
53     float f;
54 
55     /* This is the IEEE 754 single-precision format.  */
56     struct
57       {
58 #if	__BYTE_ORDER == __BIG_ENDIAN
59 	unsigned int negative:1;
60 	unsigned int exponent:8;
61 	unsigned int mantissa:23;
62 #endif				/* Big endian.  */
63 #if	__BYTE_ORDER == __LITTLE_ENDIAN
64 	unsigned int mantissa:23;
65 	unsigned int exponent:8;
66 	unsigned int negative:1;
67 #endif				/* Little endian.  */
68       } ieee;
69 
70     /* This format makes it easier to see if a NaN is a signalling NaN.  */
71     struct
72       {
73 #if	__BYTE_ORDER == __BIG_ENDIAN
74 	unsigned int negative:1;
75 	unsigned int exponent:8;
76 	unsigned int quiet_nan:1;
77 	unsigned int mantissa:22;
78 #endif				/* Big endian.  */
79 #if	__BYTE_ORDER == __LITTLE_ENDIAN
80 	unsigned int mantissa:22;
81 	unsigned int quiet_nan:1;
82 	unsigned int exponent:8;
83 	unsigned int negative:1;
84 #endif				/* Little endian.  */
85       } ieee_nan;
86   };
87 
88 #define IEEE754_FLOAT_BIAS	0x7f /* Added to exponent.  */
89 
90 
91 union ieee754_double
92   {
93     double d;
94 
95     /* This is the IEEE 754 double-precision format.  */
96     struct
97       {
98 #if	__BYTE_ORDER == __BIG_ENDIAN
99 	unsigned int negative:1;
100 	unsigned int exponent:11;
101 	/* Together these comprise the mantissa.  */
102 	unsigned int mantissa0:20;
103 	unsigned int mantissa1:32;
104 #endif				/* Big endian.  */
105 #if	__BYTE_ORDER == __LITTLE_ENDIAN
106 # if	__FLOAT_WORD_ORDER == __BIG_ENDIAN
107 	unsigned int mantissa0:20;
108 	unsigned int exponent:11;
109 	unsigned int negative:1;
110 	unsigned int mantissa1:32;
111 # else
112 	/* Together these comprise the mantissa.  */
113 	unsigned int mantissa1:32;
114 	unsigned int mantissa0:20;
115 	unsigned int exponent:11;
116 	unsigned int negative:1;
117 # endif
118 #endif				/* Little endian.  */
119       } ieee;
120 
121     /* This format makes it easier to see if a NaN is a signalling NaN.  */
122     struct
123       {
124 #if	__BYTE_ORDER == __BIG_ENDIAN
125 	unsigned int negative:1;
126 	unsigned int exponent:11;
127 	unsigned int quiet_nan:1;
128 	/* Together these comprise the mantissa.  */
129 	unsigned int mantissa0:19;
130 	unsigned int mantissa1:32;
131 #else
132 # if	__FLOAT_WORD_ORDER == __BIG_ENDIAN
133 	unsigned int mantissa0:19;
134 	unsigned int quiet_nan:1;
135 	unsigned int exponent:11;
136 	unsigned int negative:1;
137 	unsigned int mantissa1:32;
138 # else
139 	/* Together these comprise the mantissa.  */
140 	unsigned int mantissa1:32;
141 	unsigned int mantissa0:19;
142 	unsigned int quiet_nan:1;
143 	unsigned int exponent:11;
144 	unsigned int negative:1;
145 # endif
146 #endif
147       } ieee_nan;
148   };
149 
150 #define IEEE754_DOUBLE_BIAS	0x3ff /* Added to exponent.  */
151 
152 
153 union ieee854_long_double
154   {
155     long double d;
156 
157     /* This is the IEEE 854 double-extended-precision format.  */
158     struct
159       {
160 #if	__BYTE_ORDER == __BIG_ENDIAN
161 	unsigned int negative:1;
162 	unsigned int exponent:15;
163 	unsigned int empty:16;
164 	unsigned int mantissa0:32;
165 	unsigned int mantissa1:32;
166 #endif
167 #if	__BYTE_ORDER == __LITTLE_ENDIAN
168 # if	__FLOAT_WORD_ORDER == __BIG_ENDIAN
169 	unsigned int exponent:15;
170 	unsigned int negative:1;
171 	unsigned int empty:16;
172 	unsigned int mantissa0:32;
173 	unsigned int mantissa1:32;
174 # else
175 	unsigned int mantissa1:32;
176 	unsigned int mantissa0:32;
177 	unsigned int exponent:15;
178 	unsigned int negative:1;
179 	unsigned int empty:16;
180 # endif
181 #endif
182       } ieee;
183 
184     /* This is for NaNs in the IEEE 854 double-extended-precision format.  */
185     struct
186       {
187 #if	__BYTE_ORDER == __BIG_ENDIAN
188 	unsigned int negative:1;
189 	unsigned int exponent:15;
190 	unsigned int empty:16;
191 	unsigned int one:1;
192 	unsigned int quiet_nan:1;
193 	unsigned int mantissa0:30;
194 	unsigned int mantissa1:32;
195 #endif
196 #if	__BYTE_ORDER == __LITTLE_ENDIAN
197 # if	__FLOAT_WORD_ORDER == __BIG_ENDIAN
198 	unsigned int exponent:15;
199 	unsigned int negative:1;
200 	unsigned int empty:16;
201 	unsigned int mantissa0:30;
202 	unsigned int quiet_nan:1;
203 	unsigned int one:1;
204 	unsigned int mantissa1:32;
205 # else
206 	unsigned int mantissa1:32;
207 	unsigned int mantissa0:30;
208 	unsigned int quiet_nan:1;
209 	unsigned int one:1;
210 	unsigned int exponent:15;
211 	unsigned int negative:1;
212 	unsigned int empty:16;
213 # endif
214 #endif
215       } ieee_nan;
216   };
217 
218 #define IEEE854_LONG_DOUBLE_BIAS 0x3fff
219 
220 __END_DECLS
221 
222 #endif /* ieee754.h */
223