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