strtod.c revision 1.2 1 1.2 kleink /* $NetBSD: strtod.c,v 1.2 2006/01/25 15:27:42 kleink Exp $ */
2 1.1 kleink
3 1.1 kleink /****************************************************************
4 1.1 kleink
5 1.1 kleink The author of this software is David M. Gay.
6 1.1 kleink
7 1.1 kleink Copyright (C) 1998-2001 by Lucent Technologies
8 1.1 kleink All Rights Reserved
9 1.1 kleink
10 1.1 kleink Permission to use, copy, modify, and distribute this software and
11 1.1 kleink its documentation for any purpose and without fee is hereby
12 1.1 kleink granted, provided that the above copyright notice appear in all
13 1.1 kleink copies and that both that the copyright notice and this
14 1.1 kleink permission notice and warranty disclaimer appear in supporting
15 1.1 kleink documentation, and that the name of Lucent or any of its entities
16 1.1 kleink not be used in advertising or publicity pertaining to
17 1.1 kleink distribution of the software without specific, written prior
18 1.1 kleink permission.
19 1.1 kleink
20 1.1 kleink LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 1.1 kleink INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
22 1.1 kleink IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
23 1.1 kleink SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24 1.1 kleink WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
25 1.1 kleink IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26 1.1 kleink ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
27 1.1 kleink THIS SOFTWARE.
28 1.1 kleink
29 1.1 kleink ****************************************************************/
30 1.1 kleink
31 1.1 kleink /* Please send bug reports to David M. Gay (dmg at acm dot org,
32 1.1 kleink * with " at " changed at "@" and " dot " changed to "."). */
33 1.1 kleink
34 1.1 kleink #include "gdtoaimp.h"
35 1.1 kleink #ifndef NO_FENV_H
36 1.1 kleink #include <fenv.h>
37 1.1 kleink #endif
38 1.1 kleink
39 1.1 kleink #ifdef USE_LOCALE
40 1.1 kleink #include "locale.h"
41 1.1 kleink #endif
42 1.1 kleink
43 1.1 kleink #ifdef IEEE_Arith
44 1.1 kleink #ifndef NO_IEEE_Scale
45 1.1 kleink #define Avoid_Underflow
46 1.1 kleink #undef tinytens
47 1.1 kleink /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
48 1.1 kleink /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
49 1.1 kleink static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
50 1.1 kleink 9007199254740992.e-256
51 1.1 kleink };
52 1.1 kleink #endif
53 1.1 kleink #endif
54 1.1 kleink
55 1.1 kleink #ifdef Honor_FLT_ROUNDS
56 1.1 kleink #define Rounding rounding
57 1.1 kleink #undef Check_FLT_ROUNDS
58 1.1 kleink #define Check_FLT_ROUNDS
59 1.1 kleink #else
60 1.1 kleink #define Rounding Flt_Rounds
61 1.1 kleink #endif
62 1.1 kleink
63 1.1 kleink double
64 1.1 kleink strtod
65 1.1 kleink #ifdef KR_headers
66 1.1 kleink (s00, se) CONST char *s00; char **se;
67 1.1 kleink #else
68 1.1 kleink (CONST char *s00, char **se)
69 1.1 kleink #endif
70 1.1 kleink {
71 1.1 kleink #ifdef Avoid_Underflow
72 1.1 kleink int scale;
73 1.1 kleink #endif
74 1.1 kleink int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
75 1.1 kleink e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
76 1.1 kleink CONST char *s, *s0, *s1;
77 1.1 kleink double aadj, aadj1, adj, rv, rv0;
78 1.1 kleink Long L;
79 1.1 kleink ULong y, z;
80 1.2 kleink Bigint *bb, *bb1, *bd0;
81 1.2 kleink Bigint *bd = NULL, *bs = NULL, *delta = NULL; /* pacify gcc */
82 1.1 kleink #ifdef SET_INEXACT
83 1.1 kleink int inexact, oldinexact;
84 1.1 kleink #endif
85 1.1 kleink #ifdef Honor_FLT_ROUNDS
86 1.1 kleink int rounding;
87 1.1 kleink #endif
88 1.1 kleink
89 1.1 kleink sign = nz0 = nz = decpt = 0;
90 1.1 kleink dval(rv) = 0.;
91 1.1 kleink for(s = s00;;s++) switch(*s) {
92 1.1 kleink case '-':
93 1.1 kleink sign = 1;
94 1.2 kleink /* FALLTHROUGH */
95 1.1 kleink case '+':
96 1.1 kleink if (*++s)
97 1.1 kleink goto break2;
98 1.2 kleink /* FALLTHROUGH */
99 1.1 kleink case 0:
100 1.1 kleink goto ret0;
101 1.1 kleink case '\t':
102 1.1 kleink case '\n':
103 1.1 kleink case '\v':
104 1.1 kleink case '\f':
105 1.1 kleink case '\r':
106 1.1 kleink case ' ':
107 1.1 kleink continue;
108 1.1 kleink default:
109 1.1 kleink goto break2;
110 1.1 kleink }
111 1.1 kleink break2:
112 1.1 kleink if (*s == '0') {
113 1.1 kleink #ifndef NO_HEX_FP
114 1.1 kleink {
115 1.1 kleink static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
116 1.2 kleink Long expt;
117 1.1 kleink ULong bits[2];
118 1.1 kleink switch(s[1]) {
119 1.1 kleink case 'x':
120 1.1 kleink case 'X':
121 1.1 kleink {
122 1.1 kleink #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
123 1.1 kleink FPI fpi1 = fpi;
124 1.1 kleink switch(fegetround()) {
125 1.1 kleink case FE_TOWARDZERO: fpi1.rounding = 0; break;
126 1.1 kleink case FE_UPWARD: fpi1.rounding = 2; break;
127 1.1 kleink case FE_DOWNWARD: fpi1.rounding = 3;
128 1.1 kleink }
129 1.1 kleink #else
130 1.1 kleink #define fpi1 fpi
131 1.1 kleink #endif
132 1.2 kleink switch((i = gethex(&s, &fpi1, &expt, &bb, sign)) & STRTOG_Retmask) {
133 1.1 kleink case STRTOG_NoNumber:
134 1.1 kleink s = s00;
135 1.1 kleink sign = 0;
136 1.2 kleink /* FALLTHROUGH */
137 1.1 kleink case STRTOG_Zero:
138 1.1 kleink break;
139 1.1 kleink default:
140 1.1 kleink if (bb) {
141 1.1 kleink copybits(bits, fpi.nbits, bb);
142 1.1 kleink Bfree(bb);
143 1.1 kleink }
144 1.2 kleink ULtod((/* LINTED */(U*)&rv)->L, bits, expt, i);
145 1.1 kleink }}
146 1.1 kleink goto ret;
147 1.1 kleink }
148 1.1 kleink }
149 1.1 kleink #endif
150 1.1 kleink nz0 = 1;
151 1.1 kleink while(*++s == '0') ;
152 1.1 kleink if (!*s)
153 1.1 kleink goto ret;
154 1.1 kleink }
155 1.1 kleink s0 = s;
156 1.1 kleink y = z = 0;
157 1.1 kleink for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
158 1.1 kleink if (nd < 9)
159 1.1 kleink y = 10*y + c - '0';
160 1.1 kleink else if (nd < 16)
161 1.1 kleink z = 10*z + c - '0';
162 1.1 kleink nd0 = nd;
163 1.1 kleink #ifdef USE_LOCALE
164 1.1 kleink if (c == *localeconv()->decimal_point)
165 1.1 kleink #else
166 1.1 kleink if (c == '.')
167 1.1 kleink #endif
168 1.1 kleink {
169 1.1 kleink decpt = 1;
170 1.1 kleink c = *++s;
171 1.1 kleink if (!nd) {
172 1.1 kleink for(; c == '0'; c = *++s)
173 1.1 kleink nz++;
174 1.1 kleink if (c > '0' && c <= '9') {
175 1.1 kleink s0 = s;
176 1.1 kleink nf += nz;
177 1.1 kleink nz = 0;
178 1.1 kleink goto have_dig;
179 1.1 kleink }
180 1.1 kleink goto dig_done;
181 1.1 kleink }
182 1.1 kleink for(; c >= '0' && c <= '9'; c = *++s) {
183 1.1 kleink have_dig:
184 1.1 kleink nz++;
185 1.1 kleink if (c -= '0') {
186 1.1 kleink nf += nz;
187 1.1 kleink for(i = 1; i < nz; i++)
188 1.1 kleink if (nd++ < 9)
189 1.1 kleink y *= 10;
190 1.1 kleink else if (nd <= DBL_DIG + 1)
191 1.1 kleink z *= 10;
192 1.1 kleink if (nd++ < 9)
193 1.1 kleink y = 10*y + c;
194 1.1 kleink else if (nd <= DBL_DIG + 1)
195 1.1 kleink z = 10*z + c;
196 1.1 kleink nz = 0;
197 1.1 kleink }
198 1.1 kleink }
199 1.1 kleink }
200 1.1 kleink dig_done:
201 1.1 kleink e = 0;
202 1.1 kleink if (c == 'e' || c == 'E') {
203 1.1 kleink if (!nd && !nz && !nz0) {
204 1.1 kleink goto ret0;
205 1.1 kleink }
206 1.1 kleink s00 = s;
207 1.1 kleink esign = 0;
208 1.1 kleink switch(c = *++s) {
209 1.1 kleink case '-':
210 1.1 kleink esign = 1;
211 1.2 kleink /* FALLTHROUGH */
212 1.1 kleink case '+':
213 1.1 kleink c = *++s;
214 1.1 kleink }
215 1.1 kleink if (c >= '0' && c <= '9') {
216 1.1 kleink while(c == '0')
217 1.1 kleink c = *++s;
218 1.1 kleink if (c > '0' && c <= '9') {
219 1.1 kleink L = c - '0';
220 1.1 kleink s1 = s;
221 1.1 kleink while((c = *++s) >= '0' && c <= '9')
222 1.1 kleink L = 10*L + c - '0';
223 1.1 kleink if (s - s1 > 8 || L > 19999)
224 1.1 kleink /* Avoid confusion from exponents
225 1.1 kleink * so large that e might overflow.
226 1.1 kleink */
227 1.1 kleink e = 19999; /* safe for 16 bit ints */
228 1.1 kleink else
229 1.1 kleink e = (int)L;
230 1.1 kleink if (esign)
231 1.1 kleink e = -e;
232 1.1 kleink }
233 1.1 kleink else
234 1.1 kleink e = 0;
235 1.1 kleink }
236 1.1 kleink else
237 1.1 kleink s = s00;
238 1.1 kleink }
239 1.1 kleink if (!nd) {
240 1.1 kleink if (!nz && !nz0) {
241 1.1 kleink #ifdef INFNAN_CHECK
242 1.1 kleink /* Check for Nan and Infinity */
243 1.1 kleink ULong bits[2];
244 1.1 kleink static FPI fpinan = /* only 52 explicit bits */
245 1.1 kleink { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
246 1.1 kleink if (!decpt)
247 1.1 kleink switch(c) {
248 1.1 kleink case 'i':
249 1.1 kleink case 'I':
250 1.1 kleink if (match(&s,"nf")) {
251 1.1 kleink --s;
252 1.1 kleink if (!match(&s,"inity"))
253 1.1 kleink ++s;
254 1.1 kleink word0(rv) = 0x7ff00000;
255 1.1 kleink word1(rv) = 0;
256 1.1 kleink goto ret;
257 1.1 kleink }
258 1.1 kleink break;
259 1.1 kleink case 'n':
260 1.1 kleink case 'N':
261 1.1 kleink if (match(&s, "an")) {
262 1.1 kleink #ifndef No_Hex_NaN
263 1.1 kleink if (*s == '(' /*)*/
264 1.1 kleink && hexnan(&s, &fpinan, bits)
265 1.1 kleink == STRTOG_NaNbits) {
266 1.1 kleink word0(rv) = 0x7ff00000 | bits[1];
267 1.1 kleink word1(rv) = bits[0];
268 1.1 kleink }
269 1.1 kleink else {
270 1.1 kleink #endif
271 1.1 kleink word0(rv) = NAN_WORD0;
272 1.1 kleink word1(rv) = NAN_WORD1;
273 1.1 kleink #ifndef No_Hex_NaN
274 1.1 kleink }
275 1.1 kleink #endif
276 1.1 kleink goto ret;
277 1.1 kleink }
278 1.1 kleink }
279 1.1 kleink #endif /* INFNAN_CHECK */
280 1.1 kleink ret0:
281 1.1 kleink s = s00;
282 1.1 kleink sign = 0;
283 1.1 kleink }
284 1.1 kleink goto ret;
285 1.1 kleink }
286 1.1 kleink e1 = e -= nf;
287 1.1 kleink
288 1.1 kleink /* Now we have nd0 digits, starting at s0, followed by a
289 1.1 kleink * decimal point, followed by nd-nd0 digits. The number we're
290 1.1 kleink * after is the integer represented by those digits times
291 1.1 kleink * 10**e */
292 1.1 kleink
293 1.1 kleink if (!nd0)
294 1.1 kleink nd0 = nd;
295 1.1 kleink k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
296 1.1 kleink dval(rv) = y;
297 1.1 kleink if (k > 9) {
298 1.1 kleink #ifdef SET_INEXACT
299 1.1 kleink if (k > DBL_DIG)
300 1.1 kleink oldinexact = get_inexact();
301 1.1 kleink #endif
302 1.1 kleink dval(rv) = tens[k - 9] * dval(rv) + z;
303 1.1 kleink }
304 1.1 kleink bd0 = 0;
305 1.1 kleink if (nd <= DBL_DIG
306 1.1 kleink #ifndef RND_PRODQUOT
307 1.1 kleink #ifndef Honor_FLT_ROUNDS
308 1.1 kleink && Flt_Rounds == 1
309 1.1 kleink #endif
310 1.1 kleink #endif
311 1.1 kleink ) {
312 1.1 kleink if (!e)
313 1.1 kleink goto ret;
314 1.1 kleink if (e > 0) {
315 1.1 kleink if (e <= Ten_pmax) {
316 1.1 kleink #ifdef VAX
317 1.1 kleink goto vax_ovfl_check;
318 1.1 kleink #else
319 1.1 kleink #ifdef Honor_FLT_ROUNDS
320 1.1 kleink /* round correctly FLT_ROUNDS = 2 or 3 */
321 1.1 kleink if (sign) {
322 1.1 kleink rv = -rv;
323 1.1 kleink sign = 0;
324 1.1 kleink }
325 1.1 kleink #endif
326 1.1 kleink /* rv = */ rounded_product(dval(rv), tens[e]);
327 1.1 kleink goto ret;
328 1.1 kleink #endif
329 1.1 kleink }
330 1.1 kleink i = DBL_DIG - nd;
331 1.1 kleink if (e <= Ten_pmax + i) {
332 1.1 kleink /* A fancier test would sometimes let us do
333 1.1 kleink * this for larger i values.
334 1.1 kleink */
335 1.1 kleink #ifdef Honor_FLT_ROUNDS
336 1.1 kleink /* round correctly FLT_ROUNDS = 2 or 3 */
337 1.1 kleink if (sign) {
338 1.1 kleink rv = -rv;
339 1.1 kleink sign = 0;
340 1.1 kleink }
341 1.1 kleink #endif
342 1.1 kleink e -= i;
343 1.1 kleink dval(rv) *= tens[i];
344 1.1 kleink #ifdef VAX
345 1.1 kleink /* VAX exponent range is so narrow we must
346 1.1 kleink * worry about overflow here...
347 1.1 kleink */
348 1.1 kleink vax_ovfl_check:
349 1.1 kleink word0(rv) -= P*Exp_msk1;
350 1.1 kleink /* rv = */ rounded_product(dval(rv), tens[e]);
351 1.1 kleink if ((word0(rv) & Exp_mask)
352 1.1 kleink > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
353 1.1 kleink goto ovfl;
354 1.1 kleink word0(rv) += P*Exp_msk1;
355 1.1 kleink #else
356 1.1 kleink /* rv = */ rounded_product(dval(rv), tens[e]);
357 1.1 kleink #endif
358 1.1 kleink goto ret;
359 1.1 kleink }
360 1.1 kleink }
361 1.1 kleink #ifndef Inaccurate_Divide
362 1.1 kleink else if (e >= -Ten_pmax) {
363 1.1 kleink #ifdef Honor_FLT_ROUNDS
364 1.1 kleink /* round correctly FLT_ROUNDS = 2 or 3 */
365 1.1 kleink if (sign) {
366 1.1 kleink rv = -rv;
367 1.1 kleink sign = 0;
368 1.1 kleink }
369 1.1 kleink #endif
370 1.1 kleink /* rv = */ rounded_quotient(dval(rv), tens[-e]);
371 1.1 kleink goto ret;
372 1.1 kleink }
373 1.1 kleink #endif
374 1.1 kleink }
375 1.1 kleink e1 += nd - k;
376 1.1 kleink
377 1.1 kleink #ifdef IEEE_Arith
378 1.1 kleink #ifdef SET_INEXACT
379 1.1 kleink inexact = 1;
380 1.1 kleink if (k <= DBL_DIG)
381 1.1 kleink oldinexact = get_inexact();
382 1.1 kleink #endif
383 1.1 kleink #ifdef Avoid_Underflow
384 1.1 kleink scale = 0;
385 1.1 kleink #endif
386 1.1 kleink #ifdef Honor_FLT_ROUNDS
387 1.1 kleink if ((rounding = Flt_Rounds) >= 2) {
388 1.1 kleink if (sign)
389 1.1 kleink rounding = rounding == 2 ? 0 : 2;
390 1.1 kleink else
391 1.1 kleink if (rounding != 2)
392 1.1 kleink rounding = 0;
393 1.1 kleink }
394 1.1 kleink #endif
395 1.1 kleink #endif /*IEEE_Arith*/
396 1.1 kleink
397 1.1 kleink /* Get starting approximation = rv * 10**e1 */
398 1.1 kleink
399 1.1 kleink if (e1 > 0) {
400 1.1 kleink if ( (i = e1 & 15) !=0)
401 1.1 kleink dval(rv) *= tens[i];
402 1.1 kleink if (e1 &= ~15) {
403 1.1 kleink if (e1 > DBL_MAX_10_EXP) {
404 1.1 kleink ovfl:
405 1.1 kleink #ifndef NO_ERRNO
406 1.1 kleink errno = ERANGE;
407 1.1 kleink #endif
408 1.1 kleink /* Can't trust HUGE_VAL */
409 1.1 kleink #ifdef IEEE_Arith
410 1.1 kleink #ifdef Honor_FLT_ROUNDS
411 1.1 kleink switch(rounding) {
412 1.1 kleink case 0: /* toward 0 */
413 1.1 kleink case 3: /* toward -infinity */
414 1.1 kleink word0(rv) = Big0;
415 1.1 kleink word1(rv) = Big1;
416 1.1 kleink break;
417 1.1 kleink default:
418 1.1 kleink word0(rv) = Exp_mask;
419 1.1 kleink word1(rv) = 0;
420 1.1 kleink }
421 1.1 kleink #else /*Honor_FLT_ROUNDS*/
422 1.1 kleink word0(rv) = Exp_mask;
423 1.1 kleink word1(rv) = 0;
424 1.1 kleink #endif /*Honor_FLT_ROUNDS*/
425 1.1 kleink #ifdef SET_INEXACT
426 1.1 kleink /* set overflow bit */
427 1.1 kleink dval(rv0) = 1e300;
428 1.1 kleink dval(rv0) *= dval(rv0);
429 1.1 kleink #endif
430 1.1 kleink #else /*IEEE_Arith*/
431 1.1 kleink word0(rv) = Big0;
432 1.1 kleink word1(rv) = Big1;
433 1.1 kleink #endif /*IEEE_Arith*/
434 1.1 kleink if (bd0)
435 1.1 kleink goto retfree;
436 1.1 kleink goto ret;
437 1.1 kleink }
438 1.2 kleink e1 = (unsigned int)e1 >> 4;
439 1.2 kleink for(j = 0; e1 > 1; j++, e1 = (unsigned int)e1 >> 1)
440 1.1 kleink if (e1 & 1)
441 1.1 kleink dval(rv) *= bigtens[j];
442 1.1 kleink /* The last multiplication could overflow. */
443 1.1 kleink word0(rv) -= P*Exp_msk1;
444 1.1 kleink dval(rv) *= bigtens[j];
445 1.1 kleink if ((z = word0(rv) & Exp_mask)
446 1.1 kleink > Exp_msk1*(DBL_MAX_EXP+Bias-P))
447 1.1 kleink goto ovfl;
448 1.1 kleink if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
449 1.1 kleink /* set to largest number */
450 1.1 kleink /* (Can't trust DBL_MAX) */
451 1.1 kleink word0(rv) = Big0;
452 1.1 kleink word1(rv) = Big1;
453 1.1 kleink }
454 1.1 kleink else
455 1.1 kleink word0(rv) += P*Exp_msk1;
456 1.1 kleink }
457 1.1 kleink }
458 1.1 kleink else if (e1 < 0) {
459 1.1 kleink e1 = -e1;
460 1.1 kleink if ( (i = e1 & 15) !=0)
461 1.1 kleink dval(rv) /= tens[i];
462 1.1 kleink if (e1 >>= 4) {
463 1.1 kleink if (e1 >= 1 << n_bigtens)
464 1.1 kleink goto undfl;
465 1.1 kleink #ifdef Avoid_Underflow
466 1.1 kleink if (e1 & Scale_Bit)
467 1.1 kleink scale = 2*P;
468 1.2 kleink for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
469 1.1 kleink if (e1 & 1)
470 1.1 kleink dval(rv) *= tinytens[j];
471 1.1 kleink if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
472 1.1 kleink >> Exp_shift)) > 0) {
473 1.1 kleink /* scaled rv is denormal; zap j low bits */
474 1.1 kleink if (j >= 32) {
475 1.1 kleink word1(rv) = 0;
476 1.1 kleink if (j >= 53)
477 1.1 kleink word0(rv) = (P+2)*Exp_msk1;
478 1.1 kleink else
479 1.2 kleink word0(rv) &= 0xffffffff << (j-32);
480 1.1 kleink }
481 1.1 kleink else
482 1.1 kleink word1(rv) &= 0xffffffff << j;
483 1.1 kleink }
484 1.1 kleink #else
485 1.1 kleink for(j = 0; e1 > 1; j++, e1 >>= 1)
486 1.1 kleink if (e1 & 1)
487 1.1 kleink dval(rv) *= tinytens[j];
488 1.1 kleink /* The last multiplication could underflow. */
489 1.1 kleink dval(rv0) = dval(rv);
490 1.1 kleink dval(rv) *= tinytens[j];
491 1.1 kleink if (!dval(rv)) {
492 1.1 kleink dval(rv) = 2.*dval(rv0);
493 1.1 kleink dval(rv) *= tinytens[j];
494 1.1 kleink #endif
495 1.1 kleink if (!dval(rv)) {
496 1.1 kleink undfl:
497 1.1 kleink dval(rv) = 0.;
498 1.1 kleink #ifndef NO_ERRNO
499 1.1 kleink errno = ERANGE;
500 1.1 kleink #endif
501 1.1 kleink if (bd0)
502 1.1 kleink goto retfree;
503 1.1 kleink goto ret;
504 1.1 kleink }
505 1.1 kleink #ifndef Avoid_Underflow
506 1.1 kleink word0(rv) = Tiny0;
507 1.1 kleink word1(rv) = Tiny1;
508 1.1 kleink /* The refinement below will clean
509 1.1 kleink * this approximation up.
510 1.1 kleink */
511 1.1 kleink }
512 1.1 kleink #endif
513 1.1 kleink }
514 1.1 kleink }
515 1.1 kleink
516 1.1 kleink /* Now the hard part -- adjusting rv to the correct value.*/
517 1.1 kleink
518 1.1 kleink /* Put digits into bd: true value = bd * 10^e */
519 1.1 kleink
520 1.1 kleink bd0 = s2b(s0, nd0, nd, y);
521 1.1 kleink
522 1.1 kleink for(;;) {
523 1.1 kleink bd = Balloc(bd0->k);
524 1.1 kleink Bcopy(bd, bd0);
525 1.1 kleink bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
526 1.1 kleink bs = i2b(1);
527 1.1 kleink
528 1.1 kleink if (e >= 0) {
529 1.1 kleink bb2 = bb5 = 0;
530 1.1 kleink bd2 = bd5 = e;
531 1.1 kleink }
532 1.1 kleink else {
533 1.1 kleink bb2 = bb5 = -e;
534 1.1 kleink bd2 = bd5 = 0;
535 1.1 kleink }
536 1.1 kleink if (bbe >= 0)
537 1.1 kleink bb2 += bbe;
538 1.1 kleink else
539 1.1 kleink bd2 -= bbe;
540 1.1 kleink bs2 = bb2;
541 1.1 kleink #ifdef Honor_FLT_ROUNDS
542 1.1 kleink if (rounding != 1)
543 1.1 kleink bs2++;
544 1.1 kleink #endif
545 1.1 kleink #ifdef Avoid_Underflow
546 1.1 kleink j = bbe - scale;
547 1.1 kleink i = j + bbbits - 1; /* logb(rv) */
548 1.1 kleink if (i < Emin) /* denormal */
549 1.1 kleink j += P - Emin;
550 1.1 kleink else
551 1.1 kleink j = P + 1 - bbbits;
552 1.1 kleink #else /*Avoid_Underflow*/
553 1.1 kleink #ifdef Sudden_Underflow
554 1.1 kleink #ifdef IBM
555 1.1 kleink j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
556 1.1 kleink #else
557 1.1 kleink j = P + 1 - bbbits;
558 1.1 kleink #endif
559 1.1 kleink #else /*Sudden_Underflow*/
560 1.1 kleink j = bbe;
561 1.1 kleink i = j + bbbits - 1; /* logb(rv) */
562 1.1 kleink if (i < Emin) /* denormal */
563 1.1 kleink j += P - Emin;
564 1.1 kleink else
565 1.1 kleink j = P + 1 - bbbits;
566 1.1 kleink #endif /*Sudden_Underflow*/
567 1.1 kleink #endif /*Avoid_Underflow*/
568 1.1 kleink bb2 += j;
569 1.1 kleink bd2 += j;
570 1.1 kleink #ifdef Avoid_Underflow
571 1.1 kleink bd2 += scale;
572 1.1 kleink #endif
573 1.1 kleink i = bb2 < bd2 ? bb2 : bd2;
574 1.1 kleink if (i > bs2)
575 1.1 kleink i = bs2;
576 1.1 kleink if (i > 0) {
577 1.1 kleink bb2 -= i;
578 1.1 kleink bd2 -= i;
579 1.1 kleink bs2 -= i;
580 1.1 kleink }
581 1.1 kleink if (bb5 > 0) {
582 1.1 kleink bs = pow5mult(bs, bb5);
583 1.1 kleink bb1 = mult(bs, bb);
584 1.1 kleink Bfree(bb);
585 1.1 kleink bb = bb1;
586 1.1 kleink }
587 1.1 kleink if (bb2 > 0)
588 1.1 kleink bb = lshift(bb, bb2);
589 1.1 kleink if (bd5 > 0)
590 1.1 kleink bd = pow5mult(bd, bd5);
591 1.1 kleink if (bd2 > 0)
592 1.1 kleink bd = lshift(bd, bd2);
593 1.1 kleink if (bs2 > 0)
594 1.1 kleink bs = lshift(bs, bs2);
595 1.1 kleink delta = diff(bb, bd);
596 1.1 kleink dsign = delta->sign;
597 1.1 kleink delta->sign = 0;
598 1.1 kleink i = cmp(delta, bs);
599 1.1 kleink #ifdef Honor_FLT_ROUNDS
600 1.1 kleink if (rounding != 1) {
601 1.1 kleink if (i < 0) {
602 1.1 kleink /* Error is less than an ulp */
603 1.1 kleink if (!delta->x[0] && delta->wds <= 1) {
604 1.1 kleink /* exact */
605 1.1 kleink #ifdef SET_INEXACT
606 1.1 kleink inexact = 0;
607 1.1 kleink #endif
608 1.1 kleink break;
609 1.1 kleink }
610 1.1 kleink if (rounding) {
611 1.1 kleink if (dsign) {
612 1.1 kleink adj = 1.;
613 1.1 kleink goto apply_adj;
614 1.1 kleink }
615 1.1 kleink }
616 1.1 kleink else if (!dsign) {
617 1.1 kleink adj = -1.;
618 1.1 kleink if (!word1(rv)
619 1.1 kleink && !(word0(rv) & Frac_mask)) {
620 1.1 kleink y = word0(rv) & Exp_mask;
621 1.1 kleink #ifdef Avoid_Underflow
622 1.1 kleink if (!scale || y > 2*P*Exp_msk1)
623 1.1 kleink #else
624 1.1 kleink if (y)
625 1.1 kleink #endif
626 1.1 kleink {
627 1.1 kleink delta = lshift(delta,Log2P);
628 1.1 kleink if (cmp(delta, bs) <= 0)
629 1.1 kleink adj = -0.5;
630 1.1 kleink }
631 1.1 kleink }
632 1.1 kleink apply_adj:
633 1.1 kleink #ifdef Avoid_Underflow
634 1.1 kleink if (scale && (y = word0(rv) & Exp_mask)
635 1.1 kleink <= 2*P*Exp_msk1)
636 1.1 kleink word0(adj) += (2*P+1)*Exp_msk1 - y;
637 1.1 kleink #else
638 1.1 kleink #ifdef Sudden_Underflow
639 1.1 kleink if ((word0(rv) & Exp_mask) <=
640 1.1 kleink P*Exp_msk1) {
641 1.1 kleink word0(rv) += P*Exp_msk1;
642 1.1 kleink dval(rv) += adj*ulp(dval(rv));
643 1.1 kleink word0(rv) -= P*Exp_msk1;
644 1.1 kleink }
645 1.1 kleink else
646 1.1 kleink #endif /*Sudden_Underflow*/
647 1.1 kleink #endif /*Avoid_Underflow*/
648 1.1 kleink dval(rv) += adj*ulp(dval(rv));
649 1.1 kleink }
650 1.1 kleink break;
651 1.1 kleink }
652 1.1 kleink adj = ratio(delta, bs);
653 1.1 kleink if (adj < 1.)
654 1.1 kleink adj = 1.;
655 1.1 kleink if (adj <= 0x7ffffffe) {
656 1.1 kleink /* adj = rounding ? ceil(adj) : floor(adj); */
657 1.1 kleink y = adj;
658 1.1 kleink if (y != adj) {
659 1.1 kleink if (!((rounding>>1) ^ dsign))
660 1.1 kleink y++;
661 1.1 kleink adj = y;
662 1.1 kleink }
663 1.1 kleink }
664 1.1 kleink #ifdef Avoid_Underflow
665 1.1 kleink if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
666 1.1 kleink word0(adj) += (2*P+1)*Exp_msk1 - y;
667 1.1 kleink #else
668 1.1 kleink #ifdef Sudden_Underflow
669 1.1 kleink if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
670 1.1 kleink word0(rv) += P*Exp_msk1;
671 1.1 kleink adj *= ulp(dval(rv));
672 1.1 kleink if (dsign)
673 1.1 kleink dval(rv) += adj;
674 1.1 kleink else
675 1.1 kleink dval(rv) -= adj;
676 1.1 kleink word0(rv) -= P*Exp_msk1;
677 1.1 kleink goto cont;
678 1.1 kleink }
679 1.1 kleink #endif /*Sudden_Underflow*/
680 1.1 kleink #endif /*Avoid_Underflow*/
681 1.1 kleink adj *= ulp(dval(rv));
682 1.1 kleink if (dsign)
683 1.1 kleink dval(rv) += adj;
684 1.1 kleink else
685 1.1 kleink dval(rv) -= adj;
686 1.1 kleink goto cont;
687 1.1 kleink }
688 1.1 kleink #endif /*Honor_FLT_ROUNDS*/
689 1.1 kleink
690 1.1 kleink if (i < 0) {
691 1.1 kleink /* Error is less than half an ulp -- check for
692 1.1 kleink * special case of mantissa a power of two.
693 1.1 kleink */
694 1.1 kleink if (dsign || word1(rv) || word0(rv) & Bndry_mask
695 1.1 kleink #ifdef IEEE_Arith
696 1.1 kleink #ifdef Avoid_Underflow
697 1.1 kleink || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
698 1.1 kleink #else
699 1.1 kleink || (word0(rv) & Exp_mask) <= Exp_msk1
700 1.1 kleink #endif
701 1.1 kleink #endif
702 1.1 kleink ) {
703 1.1 kleink #ifdef SET_INEXACT
704 1.1 kleink if (!delta->x[0] && delta->wds <= 1)
705 1.1 kleink inexact = 0;
706 1.1 kleink #endif
707 1.1 kleink break;
708 1.1 kleink }
709 1.1 kleink if (!delta->x[0] && delta->wds <= 1) {
710 1.1 kleink /* exact result */
711 1.1 kleink #ifdef SET_INEXACT
712 1.1 kleink inexact = 0;
713 1.1 kleink #endif
714 1.1 kleink break;
715 1.1 kleink }
716 1.1 kleink delta = lshift(delta,Log2P);
717 1.1 kleink if (cmp(delta, bs) > 0)
718 1.1 kleink goto drop_down;
719 1.1 kleink break;
720 1.1 kleink }
721 1.1 kleink if (i == 0) {
722 1.1 kleink /* exactly half-way between */
723 1.1 kleink if (dsign) {
724 1.1 kleink if ((word0(rv) & Bndry_mask1) == Bndry_mask1
725 1.1 kleink && word1(rv) == (
726 1.1 kleink #ifdef Avoid_Underflow
727 1.1 kleink (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
728 1.1 kleink ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
729 1.1 kleink #endif
730 1.1 kleink 0xffffffff)) {
731 1.1 kleink /*boundary case -- increment exponent*/
732 1.1 kleink word0(rv) = (word0(rv) & Exp_mask)
733 1.1 kleink + Exp_msk1
734 1.1 kleink #ifdef IBM
735 1.1 kleink | Exp_msk1 >> 4
736 1.1 kleink #endif
737 1.1 kleink ;
738 1.1 kleink word1(rv) = 0;
739 1.1 kleink #ifdef Avoid_Underflow
740 1.1 kleink dsign = 0;
741 1.1 kleink #endif
742 1.1 kleink break;
743 1.1 kleink }
744 1.1 kleink }
745 1.1 kleink else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
746 1.1 kleink drop_down:
747 1.1 kleink /* boundary case -- decrement exponent */
748 1.1 kleink #ifdef Sudden_Underflow /*{{*/
749 1.1 kleink L = word0(rv) & Exp_mask;
750 1.1 kleink #ifdef IBM
751 1.1 kleink if (L < Exp_msk1)
752 1.1 kleink #else
753 1.1 kleink #ifdef Avoid_Underflow
754 1.1 kleink if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
755 1.1 kleink #else
756 1.1 kleink if (L <= Exp_msk1)
757 1.1 kleink #endif /*Avoid_Underflow*/
758 1.1 kleink #endif /*IBM*/
759 1.1 kleink goto undfl;
760 1.1 kleink L -= Exp_msk1;
761 1.1 kleink #else /*Sudden_Underflow}{*/
762 1.1 kleink #ifdef Avoid_Underflow
763 1.1 kleink if (scale) {
764 1.1 kleink L = word0(rv) & Exp_mask;
765 1.1 kleink if (L <= (2*P+1)*Exp_msk1) {
766 1.1 kleink if (L > (P+2)*Exp_msk1)
767 1.1 kleink /* round even ==> */
768 1.1 kleink /* accept rv */
769 1.1 kleink break;
770 1.1 kleink /* rv = smallest denormal */
771 1.1 kleink goto undfl;
772 1.1 kleink }
773 1.1 kleink }
774 1.1 kleink #endif /*Avoid_Underflow*/
775 1.1 kleink L = (word0(rv) & Exp_mask) - Exp_msk1;
776 1.1 kleink #endif /*Sudden_Underflow}*/
777 1.1 kleink word0(rv) = L | Bndry_mask1;
778 1.1 kleink word1(rv) = 0xffffffff;
779 1.1 kleink #ifdef IBM
780 1.1 kleink goto cont;
781 1.1 kleink #else
782 1.1 kleink break;
783 1.1 kleink #endif
784 1.1 kleink }
785 1.1 kleink #ifndef ROUND_BIASED
786 1.1 kleink if (!(word1(rv) & LSB))
787 1.1 kleink break;
788 1.1 kleink #endif
789 1.1 kleink if (dsign)
790 1.1 kleink dval(rv) += ulp(dval(rv));
791 1.1 kleink #ifndef ROUND_BIASED
792 1.1 kleink else {
793 1.1 kleink dval(rv) -= ulp(dval(rv));
794 1.1 kleink #ifndef Sudden_Underflow
795 1.1 kleink if (!dval(rv))
796 1.1 kleink goto undfl;
797 1.1 kleink #endif
798 1.1 kleink }
799 1.1 kleink #ifdef Avoid_Underflow
800 1.1 kleink dsign = 1 - dsign;
801 1.1 kleink #endif
802 1.1 kleink #endif
803 1.1 kleink break;
804 1.1 kleink }
805 1.1 kleink if ((aadj = ratio(delta, bs)) <= 2.) {
806 1.1 kleink if (dsign)
807 1.1 kleink aadj = aadj1 = 1.;
808 1.1 kleink else if (word1(rv) || word0(rv) & Bndry_mask) {
809 1.1 kleink #ifndef Sudden_Underflow
810 1.1 kleink if (word1(rv) == Tiny1 && !word0(rv))
811 1.1 kleink goto undfl;
812 1.1 kleink #endif
813 1.1 kleink aadj = 1.;
814 1.1 kleink aadj1 = -1.;
815 1.1 kleink }
816 1.1 kleink else {
817 1.1 kleink /* special case -- power of FLT_RADIX to be */
818 1.1 kleink /* rounded down... */
819 1.1 kleink
820 1.1 kleink if (aadj < 2./FLT_RADIX)
821 1.1 kleink aadj = 1./FLT_RADIX;
822 1.1 kleink else
823 1.1 kleink aadj *= 0.5;
824 1.1 kleink aadj1 = -aadj;
825 1.1 kleink }
826 1.1 kleink }
827 1.1 kleink else {
828 1.1 kleink aadj *= 0.5;
829 1.1 kleink aadj1 = dsign ? aadj : -aadj;
830 1.1 kleink #ifdef Check_FLT_ROUNDS
831 1.1 kleink switch(Rounding) {
832 1.1 kleink case 2: /* towards +infinity */
833 1.1 kleink aadj1 -= 0.5;
834 1.1 kleink break;
835 1.1 kleink case 0: /* towards 0 */
836 1.1 kleink case 3: /* towards -infinity */
837 1.1 kleink aadj1 += 0.5;
838 1.1 kleink }
839 1.1 kleink #else
840 1.1 kleink if (Flt_Rounds == 0)
841 1.1 kleink aadj1 += 0.5;
842 1.1 kleink #endif /*Check_FLT_ROUNDS*/
843 1.1 kleink }
844 1.1 kleink y = word0(rv) & Exp_mask;
845 1.1 kleink
846 1.1 kleink /* Check for overflow */
847 1.1 kleink
848 1.1 kleink if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
849 1.1 kleink dval(rv0) = dval(rv);
850 1.1 kleink word0(rv) -= P*Exp_msk1;
851 1.1 kleink adj = aadj1 * ulp(dval(rv));
852 1.1 kleink dval(rv) += adj;
853 1.1 kleink if ((word0(rv) & Exp_mask) >=
854 1.1 kleink Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
855 1.1 kleink if (word0(rv0) == Big0 && word1(rv0) == Big1)
856 1.1 kleink goto ovfl;
857 1.1 kleink word0(rv) = Big0;
858 1.1 kleink word1(rv) = Big1;
859 1.1 kleink goto cont;
860 1.1 kleink }
861 1.1 kleink else
862 1.1 kleink word0(rv) += P*Exp_msk1;
863 1.1 kleink }
864 1.1 kleink else {
865 1.1 kleink #ifdef Avoid_Underflow
866 1.1 kleink if (scale && y <= 2*P*Exp_msk1) {
867 1.1 kleink if (aadj <= 0x7fffffff) {
868 1.2 kleink if ((z = aadj) == 0)
869 1.1 kleink z = 1;
870 1.1 kleink aadj = z;
871 1.1 kleink aadj1 = dsign ? aadj : -aadj;
872 1.1 kleink }
873 1.1 kleink word0(aadj1) += (2*P+1)*Exp_msk1 - y;
874 1.1 kleink }
875 1.1 kleink adj = aadj1 * ulp(dval(rv));
876 1.1 kleink dval(rv) += adj;
877 1.1 kleink #else
878 1.1 kleink #ifdef Sudden_Underflow
879 1.1 kleink if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
880 1.1 kleink dval(rv0) = dval(rv);
881 1.1 kleink word0(rv) += P*Exp_msk1;
882 1.1 kleink adj = aadj1 * ulp(dval(rv));
883 1.1 kleink dval(rv) += adj;
884 1.1 kleink #ifdef IBM
885 1.1 kleink if ((word0(rv) & Exp_mask) < P*Exp_msk1)
886 1.1 kleink #else
887 1.1 kleink if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
888 1.1 kleink #endif
889 1.1 kleink {
890 1.1 kleink if (word0(rv0) == Tiny0
891 1.1 kleink && word1(rv0) == Tiny1)
892 1.1 kleink goto undfl;
893 1.1 kleink word0(rv) = Tiny0;
894 1.1 kleink word1(rv) = Tiny1;
895 1.1 kleink goto cont;
896 1.1 kleink }
897 1.1 kleink else
898 1.1 kleink word0(rv) -= P*Exp_msk1;
899 1.1 kleink }
900 1.1 kleink else {
901 1.1 kleink adj = aadj1 * ulp(dval(rv));
902 1.1 kleink dval(rv) += adj;
903 1.1 kleink }
904 1.1 kleink #else /*Sudden_Underflow*/
905 1.1 kleink /* Compute adj so that the IEEE rounding rules will
906 1.1 kleink * correctly round rv + adj in some half-way cases.
907 1.1 kleink * If rv * ulp(rv) is denormalized (i.e.,
908 1.1 kleink * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
909 1.1 kleink * trouble from bits lost to denormalization;
910 1.1 kleink * example: 1.2e-307 .
911 1.1 kleink */
912 1.1 kleink if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
913 1.1 kleink aadj1 = (double)(int)(aadj + 0.5);
914 1.1 kleink if (!dsign)
915 1.1 kleink aadj1 = -aadj1;
916 1.1 kleink }
917 1.1 kleink adj = aadj1 * ulp(dval(rv));
918 1.1 kleink dval(rv) += adj;
919 1.1 kleink #endif /*Sudden_Underflow*/
920 1.1 kleink #endif /*Avoid_Underflow*/
921 1.1 kleink }
922 1.1 kleink z = word0(rv) & Exp_mask;
923 1.1 kleink #ifndef SET_INEXACT
924 1.1 kleink #ifdef Avoid_Underflow
925 1.1 kleink if (!scale)
926 1.1 kleink #endif
927 1.1 kleink if (y == z) {
928 1.1 kleink /* Can we stop now? */
929 1.1 kleink L = (Long)aadj;
930 1.1 kleink aadj -= L;
931 1.1 kleink /* The tolerances below are conservative. */
932 1.1 kleink if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
933 1.1 kleink if (aadj < .4999999 || aadj > .5000001)
934 1.1 kleink break;
935 1.1 kleink }
936 1.1 kleink else if (aadj < .4999999/FLT_RADIX)
937 1.1 kleink break;
938 1.1 kleink }
939 1.1 kleink #endif
940 1.1 kleink cont:
941 1.1 kleink Bfree(bb);
942 1.1 kleink Bfree(bd);
943 1.1 kleink Bfree(bs);
944 1.1 kleink Bfree(delta);
945 1.1 kleink }
946 1.1 kleink #ifdef SET_INEXACT
947 1.1 kleink if (inexact) {
948 1.1 kleink if (!oldinexact) {
949 1.1 kleink word0(rv0) = Exp_1 + (70 << Exp_shift);
950 1.1 kleink word1(rv0) = 0;
951 1.1 kleink dval(rv0) += 1.;
952 1.1 kleink }
953 1.1 kleink }
954 1.1 kleink else if (!oldinexact)
955 1.1 kleink clear_inexact();
956 1.1 kleink #endif
957 1.1 kleink #ifdef Avoid_Underflow
958 1.1 kleink if (scale) {
959 1.1 kleink word0(rv0) = Exp_1 - 2*P*Exp_msk1;
960 1.1 kleink word1(rv0) = 0;
961 1.1 kleink dval(rv) *= dval(rv0);
962 1.1 kleink #ifndef NO_ERRNO
963 1.1 kleink /* try to avoid the bug of testing an 8087 register value */
964 1.1 kleink if (word0(rv) == 0 && word1(rv) == 0)
965 1.1 kleink errno = ERANGE;
966 1.1 kleink #endif
967 1.1 kleink }
968 1.1 kleink #endif /* Avoid_Underflow */
969 1.1 kleink #ifdef SET_INEXACT
970 1.1 kleink if (inexact && !(word0(rv) & Exp_mask)) {
971 1.1 kleink /* set underflow bit */
972 1.1 kleink dval(rv0) = 1e-300;
973 1.1 kleink dval(rv0) *= dval(rv0);
974 1.1 kleink }
975 1.1 kleink #endif
976 1.1 kleink retfree:
977 1.1 kleink Bfree(bb);
978 1.1 kleink Bfree(bd);
979 1.1 kleink Bfree(bs);
980 1.1 kleink Bfree(bd0);
981 1.1 kleink Bfree(delta);
982 1.1 kleink ret:
983 1.1 kleink if (se)
984 1.2 kleink *se = __UNCONST(s);
985 1.1 kleink return sign ? -dval(rv) : dval(rv);
986 1.1 kleink }
987 1.1 kleink
988