Rev 4874 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 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 |
||
33 | #include |
||
34 | #include |
||
35 | #include |
||
36 | #include |
||
37 | #include |
||
38 | |||
39 | #ifdef __IEEE_LITTLE_ENDIAN |
||
40 | #define IEEE_8087 |
||
41 | #endif |
||
42 | |||
43 | #ifdef __IEEE_BIG_ENDIAN |
||
44 | #define IEEE_MC68k |
||
45 | #endif |
||
46 | |||
47 | #ifdef __Z8000__ |
||
48 | #define Just_16 |
||
49 | #endif |
||
50 | |||
51 | #ifdef Unsigned_Shifts |
||
52 | #define Sign_Extend(a,b) if (b < 0) a |= (__uint32_t)0xffff0000; |
||
53 | #else |
||
54 | #define Sign_Extend(a,b) /*no-op*/ |
||
55 | #endif |
||
56 | |||
57 | #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 |
||
58 | Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. |
||
59 | #endif |
||
60 | |||
61 | #ifdef _WANT_IO_LONG_DOUBLE |
||
62 | /* If we are going to examine or modify specific bits in a long double using |
||
63 | the lword0 or lwordx macros, then we must wrap the long double inside |
||
64 | a union. This is necessary to avoid undefined behavior according to |
||
65 | the ANSI C spec. */ |
||
66 | |||
67 | #ifdef IEEE_8087 |
||
68 | #if LDBL_MANT_DIG == 24 |
||
69 | struct ldieee |
||
70 | { |
||
71 | unsigned manh:23; |
||
72 | unsigned exp:8; |
||
73 | unsigned sign:1; |
||
74 | }; |
||
75 | #elif LDBL_MANT_DIG == 53 |
||
76 | struct ldieee |
||
77 | { |
||
78 | unsigned manl:20; |
||
79 | unsigned manh:32; |
||
80 | unsigned exp:11; |
||
81 | unsigned sign:1; |
||
82 | }; |
||
83 | #elif LDBL_MANT_DIG == 64 |
||
84 | struct ldieee |
||
85 | { |
||
86 | unsigned manl:32; |
||
87 | unsigned manh:32; |
||
88 | unsigned exp:15; |
||
89 | unsigned sign:1; |
||
90 | }; |
||
91 | #elif LDBL_MANT_DIG > 64 |
||
92 | struct ldieee |
||
93 | { |
||
94 | unsigned manl3:16; |
||
95 | unsigned manl2:32; |
||
96 | unsigned manl:32; |
||
97 | unsigned manh:32; |
||
98 | unsigned exp:15; |
||
99 | unsigned sign:1; |
||
100 | }; |
||
101 | #endif /* LDBL_MANT_DIG */ |
||
102 | #else /* !IEEE_8087 */ |
||
103 | #if LDBL_MANT_DIG == 24 |
||
104 | struct ldieee |
||
105 | { |
||
106 | unsigned sign:1; |
||
107 | unsigned exp:8; |
||
108 | unsigned manh:23; |
||
109 | }; |
||
110 | #elif LDBL_MANT_DIG == 53 |
||
111 | struct ldieee |
||
112 | { |
||
113 | unsigned sign:1; |
||
114 | unsigned exp:11; |
||
115 | unsigned manh:32; |
||
116 | unsigned manl:20; |
||
117 | }; |
||
118 | #elif LDBL_MANT_DIG == 64 |
||
119 | struct ldieee |
||
120 | { |
||
121 | unsigned sign:1; |
||
122 | unsigned exp:15; |
||
123 | unsigned manh:32; |
||
124 | unsigned manl:32; |
||
125 | }; |
||
126 | #elif LDBL_MANT_DIG > 64 |
||
127 | struct ldieee |
||
128 | { |
||
129 | unsigned sign:1; |
||
130 | unsigned exp:15; |
||
131 | unsigned manh:32; |
||
132 | unsigned manl:32; |
||
133 | unsigned manl2:32; |
||
4921 | Serge | 134 | unsigned manl3:16; |
4349 | Serge | 135 | }; |
136 | #endif /* LDBL_MANT_DIG */ |
||
137 | #endif /* !IEEE_8087 */ |
||
138 | #endif /* _WANT_IO_LONG_DOUBLE */ |
||
139 | |||
140 | /* If we are going to examine or modify specific bits in a double using |
||
141 | the word0 and/or word1 macros, then we must wrap the double inside |
||
142 | a union. This is necessary to avoid undefined behavior according to |
||
143 | the ANSI C spec. */ |
||
144 | union double_union |
||
145 | { |
||
146 | double d; |
||
147 | __uint32_t i[2]; |
||
148 | }; |
||
149 | |||
150 | #ifdef IEEE_8087 |
||
151 | #define word0(x) (x.i[1]) |
||
152 | #define word1(x) (x.i[0]) |
||
153 | #else |
||
154 | #define word0(x) (x.i[0]) |
||
155 | #define word1(x) (x.i[1]) |
||
156 | #endif |
||
157 | |||
158 | /* #define P DBL_MANT_DIG */ |
||
159 | /* Ten_pmax = floor(P*log(2)/log(5)) */ |
||
160 | /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ |
||
161 | /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ |
||
162 | /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ |
||
163 | |||
164 | #if defined(IEEE_8087) + defined(IEEE_MC68k) |
||
165 | #if defined (_DOUBLE_IS_32BITS) |
||
166 | #define Exp_shift 23 |
||
167 | #define Exp_shift1 23 |
||
168 | #define Exp_msk1 ((__uint32_t)0x00800000L) |
||
169 | #define Exp_msk11 ((__uint32_t)0x00800000L) |
||
170 | #define Exp_mask ((__uint32_t)0x7f800000L) |
||
171 | #define P 24 |
||
172 | #define Bias 127 |
||
173 | #define IEEE_Arith |
||
174 | #define Emin (-126) |
||
175 | #define Exp_1 ((__uint32_t)0x3f800000L) |
||
176 | #define Exp_11 ((__uint32_t)0x3f800000L) |
||
177 | #define Ebits 8 |
||
178 | #define Frac_mask ((__uint32_t)0x007fffffL) |
||
179 | #define Frac_mask1 ((__uint32_t)0x007fffffL) |
||
180 | #define Ten_pmax 10 |
||
181 | #define Sign_bit ((__uint32_t)0x80000000L) |
||
182 | #define Ten_pmax 10 |
||
183 | #define Bletch 2 |
||
184 | #define Bndry_mask ((__uint32_t)0x007fffffL) |
||
185 | #define Bndry_mask1 ((__uint32_t)0x007fffffL) |
||
186 | #define LSB 1 |
||
187 | #define Sign_bit ((__uint32_t)0x80000000L) |
||
188 | #define Log2P 1 |
||
189 | #define Tiny0 0 |
||
190 | #define Tiny1 1 |
||
191 | #define Quick_max 5 |
||
192 | #define Int_max 6 |
||
193 | #define Infinite(x) (word0(x) == ((__uint32_t)0x7f800000L)) |
||
194 | #undef word0 |
||
195 | #undef word1 |
||
196 | |||
197 | #define word0(x) (x.i[0]) |
||
198 | #define word1(x) 0 |
||
199 | #else |
||
200 | |||
201 | #define Exp_shift 20 |
||
202 | #define Exp_shift1 20 |
||
203 | #define Exp_msk1 ((__uint32_t)0x100000L) |
||
204 | #define Exp_msk11 ((__uint32_t)0x100000L) |
||
205 | #define Exp_mask ((__uint32_t)0x7ff00000L) |
||
206 | #define P 53 |
||
207 | #define Bias 1023 |
||
208 | #define IEEE_Arith |
||
209 | #define Emin (-1022) |
||
210 | #define Exp_1 ((__uint32_t)0x3ff00000L) |
||
211 | #define Exp_11 ((__uint32_t)0x3ff00000L) |
||
212 | #define Ebits 11 |
||
213 | #define Frac_mask ((__uint32_t)0xfffffL) |
||
214 | #define Frac_mask1 ((__uint32_t)0xfffffL) |
||
215 | #define Ten_pmax 22 |
||
216 | #define Bletch 0x10 |
||
217 | #define Bndry_mask ((__uint32_t)0xfffffL) |
||
218 | #define Bndry_mask1 ((__uint32_t)0xfffffL) |
||
219 | #define LSB 1 |
||
220 | #define Sign_bit ((__uint32_t)0x80000000L) |
||
221 | #define Log2P 1 |
||
222 | #define Tiny0 0 |
||
223 | #define Tiny1 1 |
||
224 | #define Quick_max 14 |
||
225 | #define Int_max 14 |
||
226 | #define Infinite(x) (word0(x) == ((__uint32_t)0x7ff00000L)) /* sufficient test for here */ |
||
227 | #endif |
||
228 | |||
229 | #else |
||
230 | #undef Sudden_Underflow |
||
231 | #define Sudden_Underflow |
||
232 | #ifdef IBM |
||
233 | #define Exp_shift 24 |
||
234 | #define Exp_shift1 24 |
||
235 | #define Exp_msk1 ((__uint32_t)0x1000000L) |
||
236 | #define Exp_msk11 ((__uint32_t)0x1000000L) |
||
237 | #define Exp_mask ((__uint32_t)0x7f000000L) |
||
238 | #define P 14 |
||
239 | #define Bias 65 |
||
240 | #define Exp_1 ((__uint32_t)0x41000000L) |
||
241 | #define Exp_11 ((__uint32_t)0x41000000L) |
||
242 | #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ |
||
243 | #define Frac_mask ((__uint32_t)0xffffffL) |
||
244 | #define Frac_mask1 ((__uint32_t)0xffffffL) |
||
245 | #define Bletch 4 |
||
246 | #define Ten_pmax 22 |
||
247 | #define Bndry_mask ((__uint32_t)0xefffffL) |
||
248 | #define Bndry_mask1 ((__uint32_t)0xffffffL) |
||
249 | #define LSB 1 |
||
250 | #define Sign_bit ((__uint32_t)0x80000000L) |
||
251 | #define Log2P 4 |
||
252 | #define Tiny0 ((__uint32_t)0x100000L) |
||
253 | #define Tiny1 0 |
||
254 | #define Quick_max 14 |
||
255 | #define Int_max 15 |
||
256 | #else /* VAX */ |
||
257 | #define Exp_shift 23 |
||
258 | #define Exp_shift1 7 |
||
259 | #define Exp_msk1 0x80 |
||
260 | #define Exp_msk11 ((__uint32_t)0x800000L) |
||
261 | #define Exp_mask ((__uint32_t)0x7f80L) |
||
262 | #define P 56 |
||
263 | #define Bias 129 |
||
264 | #define Exp_1 ((__uint32_t)0x40800000L) |
||
265 | #define Exp_11 ((__uint32_t)0x4080L) |
||
266 | #define Ebits 8 |
||
267 | #define Frac_mask ((__uint32_t)0x7fffffL) |
||
268 | #define Frac_mask1 ((__uint32_t)0xffff007fL) |
||
269 | #define Ten_pmax 24 |
||
270 | #define Bletch 2 |
||
271 | #define Bndry_mask ((__uint32_t)0xffff007fL) |
||
272 | #define Bndry_mask1 ((__uint32_t)0xffff007fL) |
||
273 | #define LSB ((__uint32_t)0x10000L) |
||
274 | #define Sign_bit ((__uint32_t)0x8000L) |
||
275 | #define Log2P 1 |
||
276 | #define Tiny0 0x80 |
||
277 | #define Tiny1 0 |
||
278 | #define Quick_max 15 |
||
279 | #define Int_max 15 |
||
280 | #endif |
||
281 | #endif>> |
||
282 |