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