1 /****************************************************************
2  *
3  * The author of this software is David M. Gay.
4  *
5  * Copyright (c) 1991 by AT&T.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose without fee is hereby granted, provided that this entire notice
9  * is included in all copies of any software which is or includes a copy
10  * or modification of this software and in all copies of the supporting
11  * documentation for such software.
12  *
13  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
14  * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
15  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
16  * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
17  *
18  ***************************************************************/
19 
20 /* Please send bug reports to
21 	David M. Gay
22 	AT&T Bell Laboratories, Room 2C-463
23 	600 Mountain Avenue
24 	Murray Hill, NJ 07974-2070
25 	U.S.A.
26 	dmg@research.att.com or research!dmg
27  */
28 
29 /* This header file is a modification of mprec.h that only contains floating
30    point union code. */
31 
32 #include <math.h>
33 #include <float.h>
34 #include <errno.h>
35 
36 #ifdef __IEEE_LITTLE_ENDIAN
37 #define IEEE_8087
38 #endif
39 
40 #ifdef __IEEE_BIG_ENDIAN
41 #define IEEE_MC68k
42 #endif
43 
44 #ifdef __Z8000__
45 #define Just_16
46 #endif
47 
48 #ifdef Unsigned_Shifts
49 #define Sign_Extend(a,b) if (b < 0) a |= (__uint32_t)0xffff0000;
50 #else
51 #define Sign_Extend(a,b) /*no-op*/
52 #endif
53 
54 #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
55 Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
56 #endif
57 
58 #ifdef _WANT_IO_LONG_DOUBLE
59 /* If we are going to examine or modify specific bits in a long double using
60    the lword0 or lwordx macros, then we must wrap the long double inside
61    a union.  This is necessary to avoid undefined behavior according to
62    the ANSI C spec.  */
63 
64 #ifdef IEEE_8087
65 #if LDBL_MANT_DIG == 24
66 struct ldieee
67 {
68   __uint32_t manh:23;
69   __uint32_t exp:8;
70   __uint32_t sign:1;
71 } __packed;
72 #elif LDBL_MANT_DIG == 53
73 struct ldieee
74 {
75   __uint32_t manl:20;
76   __uint32_t manh:32;
77   __uint32_t exp:11;
78   __uint32_t sign:1;
79 } __packed;
80 #elif LDBL_MANT_DIG == 64
81 struct ldieee
82 {
83   __uint32_t manl:32;
84   __uint32_t manh:32;
85   __uint32_t exp:15;
86   __uint32_t sign:1;
87 } __packed;
88 #elif LDBL_MANT_DIG > 64
89 struct ldieee
90 {
91   __uint32_t manl3:16;
92   __uint32_t manl2:32;
93   __uint32_t manl:32;
94   __uint32_t manh:32;
95   __uint32_t exp:15;
96   __uint32_t sign:1;
97 } __packed;
98 #endif /* LDBL_MANT_DIG */
99 #else  /* !IEEE_8087 */
100 #if LDBL_MANT_DIG == 24
101 struct ldieee
102 {
103   __uint32_t sign:1;
104   __uint32_t exp:8;
105   __uint32_t manh:23;
106 } __packed;
107 #elif LDBL_MANT_DIG == 53
108 struct ldieee
109 {
110   __uint32_t sign:1;
111   __uint32_t exp:11;
112   __uint32_t manh:32;
113   __uint32_t manl:20;
114 } __packed;
115 #elif LDBL_MANT_DIG == 64
116 struct ldieee
117 {
118   __uint32_t sign:1;
119   __uint32_t exp:15;
120   __uint32_t manh:32;
121   __uint32_t manl:32;
122 } __packed;
123 #elif LDBL_MANT_DIG > 64
124 struct ldieee
125 {
126   __uint32_t sign:1;
127   __uint32_t exp:15;
128   __uint32_t manh:32;
129   __uint32_t manl:32;
130   __uint32_t manl2:32;
131   __uint32_t manl3:16;
132 } __packed;
133 #endif /* LDBL_MANT_DIG */
134 #endif /* !IEEE_8087 */
135 #endif /* _WANT_IO_LONG_DOUBLE */
136 
137 /* If we are going to examine or modify specific bits in a double using
138    the word0 and/or word1 macros, then we must wrap the double inside
139    a union.  This is necessary to avoid undefined behavior according to
140    the ANSI C spec.  */
141 union double_union
142 {
143   double d;
144   __uint32_t i[2];
145 };
146 
147 #ifdef IEEE_8087
148 #define word0(x) (x.i[1])
149 #define word1(x) (x.i[0])
150 #else
151 #define word0(x) (x.i[0])
152 #define word1(x) (x.i[1])
153 #endif
154 
155 /* #define P DBL_MANT_DIG */
156 /* Ten_pmax = floor(P*log(2)/log(5)) */
157 /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
158 /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
159 /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
160 
161 #if defined(IEEE_8087) + defined(IEEE_MC68k)
162 #if defined (_DOUBLE_IS_32BITS)
163 #define Exp_shift   23
164 #define Exp_shift1  23
165 #define Exp_msk1    ((__uint32_t)0x00800000L)
166 #define Exp_msk11   ((__uint32_t)0x00800000L)
167 #define Exp_mask    ((__uint32_t)0x7f800000L)
168 #define P    	    24
169 #define Bias 	    ((__uint32_t)127)
170 #define IEEE_Arith
171 #define Emin        (-126)
172 #define Exp_1       ((__uint32_t)0x3f800000L)
173 #define Exp_11      ((__uint32_t)0x3f800000L)
174 #define Ebits 	    8
175 #define Frac_mask   ((__uint32_t)0x007fffffL)
176 #define Frac_mask1  ((__uint32_t)0x007fffffL)
177 #define Ten_pmax    10
178 #define Sign_bit    ((__uint32_t)0x80000000L)
179 #define Ten_pmax    10
180 #define Bletch	    2
181 #define Bndry_mask  ((__uint32_t)0x007fffffL)
182 #define Bndry_mask1 ((__uint32_t)0x007fffffL)
183 #define LSB 1
184 #define Sign_bit    ((__uint32_t)0x80000000L)
185 #define Log2P 	    1
186 #define Tiny0 	    0
187 #define Tiny1 	    1
188 #define Quick_max   5
189 #define Int_max     6
190 #define Infinite(x) (word0(x) == ((__uint32_t)0x7f800000L))
191 #undef word0
192 #undef word1
193 
194 #define word0(x) (x.i[0])
195 #define word1(x) 0
196 #else
197 
198 #define Exp_shift  20
199 #define Exp_shift1 20
200 #define Exp_msk1    ((__uint32_t)0x100000L)
201 #define Exp_msk11   ((__uint32_t)0x100000L)
202 #define Exp_mask  ((__uint32_t)0x7ff00000L)
203 #define P 53
204 #define Bias ((__uint32_t) 1023)
205 #define IEEE_Arith
206 #define Emin (-1022)
207 #define Exp_1  ((__uint32_t)0x3ff00000L)
208 #define Exp_11 ((__uint32_t)0x3ff00000L)
209 #define Ebits 11
210 #define Frac_mask  ((__uint32_t)0xfffffL)
211 #define Frac_mask1 ((__uint32_t)0xfffffL)
212 #define Ten_pmax 22
213 #define Bletch 0x10
214 #define Bndry_mask  ((__uint32_t)0xfffffL)
215 #define Bndry_mask1 ((__uint32_t)0xfffffL)
216 #define LSB 1
217 #define Sign_bit ((__uint32_t)0x80000000L)
218 #define Log2P 1
219 #define Tiny0 0
220 #define Tiny1 1
221 #define Quick_max 14
222 #define Int_max 14
223 #define Infinite(x) (word0(x) == ((__uint32_t)0x7ff00000L)) /* sufficient test for here */
224 #endif
225 
226 #else
227 #undef  Sudden_Underflow
228 #define Sudden_Underflow
229 #ifdef IBM
230 #define Exp_shift  24
231 #define Exp_shift1 24
232 #define Exp_msk1   ((__uint32_t)0x1000000L)
233 #define Exp_msk11  ((__uint32_t)0x1000000L)
234 #define Exp_mask  ((__uint32_t)0x7f000000L)
235 #define P 14
236 #define Bias ((__uint32_T) 65)
237 #define Exp_1  ((__uint32_t)0x41000000L)
238 #define Exp_11 ((__uint32_t)0x41000000L)
239 #define Ebits 8	/* exponent has 7 bits, but 8 is the right value in b2d */
240 #define Frac_mask  ((__uint32_t)0xffffffL)
241 #define Frac_mask1 ((__uint32_t)0xffffffL)
242 #define Bletch 4
243 #define Ten_pmax 22
244 #define Bndry_mask  ((__uint32_t)0xefffffL)
245 #define Bndry_mask1 ((__uint32_t)0xffffffL)
246 #define LSB 1
247 #define Sign_bit ((__uint32_t)0x80000000L)
248 #define Log2P 4
249 #define Tiny0 ((__uint32_t)0x100000L)
250 #define Tiny1 0
251 #define Quick_max 14
252 #define Int_max 15
253 #else /* VAX */
254 #define Exp_shift  23
255 #define Exp_shift1 7
256 #define Exp_msk1    0x80
257 #define Exp_msk11   ((__uint32_t)0x800000L)
258 #define Exp_mask  ((__uint32_t)0x7f80L)
259 #define P 56
260 #define Bias ((__uint32_t) 129)
261 #define Exp_1  ((__uint32_t)0x40800000L)
262 #define Exp_11 ((__uint32_t)0x4080L)
263 #define Ebits 8
264 #define Frac_mask  ((__uint32_t)0x7fffffL)
265 #define Frac_mask1 ((__uint32_t)0xffff007fL)
266 #define Ten_pmax 24
267 #define Bletch 2
268 #define Bndry_mask  ((__uint32_t)0xffff007fL)
269 #define Bndry_mask1 ((__uint32_t)0xffff007fL)
270 #define LSB ((__uint32_t)0x10000L)
271 #define Sign_bit ((__uint32_t)0x8000L)
272 #define Log2P 1
273 #define Tiny0 0x80
274 #define Tiny1 0
275 #define Quick_max 15
276 #define Int_max 15
277 #endif
278 #endif
279 
280 
281