Deleted Added
full compact
strtod.c (174679) strtod.c (182709)
1/****************************************************************
2
3The author of this software is David M. Gay.
4
5Copyright (C) 1998-2001 by Lucent Technologies
6All Rights Reserved
7
8Permission to use, copy, modify, and distribute this software and

--- 15 unchanged lines hidden (view full) ---

24ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25THIS SOFTWARE.
26
27****************************************************************/
28
29/* Please send bug reports to David M. Gay (dmg at acm dot org,
30 * with " at " changed at "@" and " dot " changed to "."). */
31
1/****************************************************************
2
3The author of this software is David M. Gay.
4
5Copyright (C) 1998-2001 by Lucent Technologies
6All Rights Reserved
7
8Permission to use, copy, modify, and distribute this software and

--- 15 unchanged lines hidden (view full) ---

24ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25THIS SOFTWARE.
26
27****************************************************************/
28
29/* Please send bug reports to David M. Gay (dmg at acm dot org,
30 * with " at " changed at "@" and " dot " changed to "."). */
31
32/* $FreeBSD: head/contrib/gdtoa/strtod.c 174679 2007-12-16 21:14:33Z das $ */
32/* $FreeBSD: head/contrib/gdtoa/strtod.c 182709 2008-09-03 07:23:57Z das $ */
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
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 */
47/* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */
48/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
49static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
48/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
49static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
50 9007199254740992.e-256
50 9007199254740992.*9007199254740992.e-256
51 };
52#endif
53#endif
54
55#ifdef Honor_FLT_ROUNDS
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
64strtod

--- 11 unchanged lines hidden (view full) ---

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
56#undef Check_FLT_ROUNDS
57#define Check_FLT_ROUNDS
58#else
59#define Rounding Flt_Rounds
60#endif
61
62 double
63strtod

--- 11 unchanged lines hidden (view full) ---

75 CONST char *s, *s0, *s1;
76 double aadj, aadj1, adj, rv, rv0;
77 Long L;
78 ULong y, z;
79 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
80#ifdef SET_INEXACT
81 int inexact, oldinexact;
82#endif
84#ifdef Honor_FLT_ROUNDS
85 int rounding;
86#endif
83#ifdef Honor_FLT_ROUNDS /*{*/
84 int Rounding;
85#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
86 Rounding = Flt_Rounds;
87#else /*}{*/
88 Rounding = 1;
89 switch(fegetround()) {
90 case FE_TOWARDZERO: Rounding = 0; break;
91 case FE_UPWARD: Rounding = 2; break;
92 case FE_DOWNWARD: Rounding = 3;
93 }
94#endif /*}}*/
95#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 '+':

--- 9 unchanged lines hidden (view full) ---

104 case '\r':
105 case ' ':
106 continue;
107 default:
108 goto break2;
109 }
110 break2:
111 if (*s == '0') {
96
97 sign = nz0 = nz = decpt = 0;
98 dval(rv) = 0.;
99 for(s = s00;;s++) switch(*s) {
100 case '-':
101 sign = 1;
102 /* no break */
103 case '+':

--- 9 unchanged lines hidden (view full) ---

113 case '\r':
114 case ' ':
115 continue;
116 default:
117 goto break2;
118 }
119 break2:
120 if (*s == '0') {
112#ifndef NO_HEX_FP
121#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 {
122 {
123 static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
124 Long exp;
125 ULong bits[2];
126 switch(s[1]) {
127 case 'x':
128 case 'X':
129 {
121#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
130#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) /*{{*/
122 FPI fpi1 = fpi;
131 FPI fpi1 = fpi;
132#ifdef Honor_FLT_ROUNDS /*{{*/
133 fpi1.rounding = Rounding;
134#else /*}{*/
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 }
135 switch(fegetround()) {
136 case FE_TOWARDZERO: fpi1.rounding = 0; break;
137 case FE_UPWARD: fpi1.rounding = 2; break;
138 case FE_DOWNWARD: fpi1.rounding = 3;
139 }
128#else
140#endif /*}}*/
141#else /*}{*/
129#define fpi1 fpi
142#define fpi1 fpi
130#endif
143#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) {

--- 237 unchanged lines hidden (view full) ---

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
144 switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) {
145 case STRTOG_NoNumber:
146 s = s00;
147 sign = 0;
148 case STRTOG_Zero:
149 break;
150 default:
151 if (bb) {

--- 237 unchanged lines hidden (view full) ---

389 inexact = 1;
390 if (k <= DBL_DIG)
391 oldinexact = get_inexact();
392#endif
393#ifdef Avoid_Underflow
394 scale = 0;
395#endif
396#ifdef Honor_FLT_ROUNDS
384 if ((rounding = Flt_Rounds) >= 2) {
397 if (Rounding >= 2) {
385 if (sign)
398 if (sign)
386 rounding = rounding == 2 ? 0 : 2;
399 Rounding = Rounding == 2 ? 0 : 2;
387 else
400 else
388 if (rounding != 2)
389 rounding = 0;
401 if (Rounding != 2)
402 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
403 }
404#endif
405#endif /*IEEE_Arith*/
406
407 /* Get starting approximation = rv * 10**e1 */
408
409 if (e1 > 0) {
410 if ( (i = e1 & 15) !=0)
411 dval(rv) *= tens[i];
412 if (e1 &= ~15) {
413 if (e1 > DBL_MAX_10_EXP) {
414 ovfl:
415#ifndef NO_ERRNO
416 errno = ERANGE;
417#endif
418 /* Can't trust HUGE_VAL */
419#ifdef IEEE_Arith
420#ifdef Honor_FLT_ROUNDS
408 switch(rounding) {
421 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;

--- 114 unchanged lines hidden (view full) ---

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
422 case 0: /* toward 0 */
423 case 3: /* toward -infinity */
424 word0(rv) = Big0;
425 word1(rv) = Big1;
426 break;
427 default:
428 word0(rv) = Exp_mask;
429 word1(rv) = 0;

--- 114 unchanged lines hidden (view full) ---

544 bd2 = bd5 = 0;
545 }
546 if (bbe >= 0)
547 bb2 += bbe;
548 else
549 bd2 -= bbe;
550 bs2 = bb2;
551#ifdef Honor_FLT_ROUNDS
539 if (rounding != 1)
552 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

--- 41 unchanged lines hidden (view full) ---

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
553 bs2++;
554#endif
555#ifdef Avoid_Underflow
556 j = bbe - scale;
557 i = j + bbbits - 1; /* logb(rv) */
558 if (i < Emin) /* denormal */
559 j += P - Emin;
560 else

--- 41 unchanged lines hidden (view full) ---

602 bd = lshift(bd, bd2);
603 if (bs2 > 0)
604 bs = lshift(bs, bs2);
605 delta = diff(bb, bd);
606 dsign = delta->sign;
607 delta->sign = 0;
608 i = cmp(delta, bs);
609#ifdef Honor_FLT_ROUNDS
597 if (rounding != 1) {
610 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 }
611 if (i < 0) {
612 /* Error is less than an ulp */
613 if (!delta->x[0] && delta->wds <= 1) {
614 /* exact */
615#ifdef SET_INEXACT
616 inexact = 0;
617#endif
618 break;
619 }
607 if (rounding) {
620 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)

--- 29 unchanged lines hidden (view full) ---

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) {
621 if (dsign) {
622 adj = 1.;
623 goto apply_adj;
624 }
625 }
626 else if (!dsign) {
627 adj = -1.;
628 if (!word1(rv)

--- 29 unchanged lines hidden (view full) ---

658 dval(rv) += adj*ulp(dval(rv));
659 }
660 break;
661 }
662 adj = ratio(delta, bs);
663 if (adj < 1.)
664 adj = 1.;
665 if (adj <= 0x7ffffffe) {
653 /* adj = rounding ? ceil(adj) : floor(adj); */
666 /* adj = Rounding ? ceil(adj) : floor(adj); */
654 y = adj;
655 if (y != adj) {
667 y = adj;
668 if (y != adj) {
656 if (!((rounding>>1) ^ dsign))
669 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

--- 6 unchanged lines hidden (view full) ---

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));
670 y++;
671 adj = y;
672 }
673 }
674#ifdef Avoid_Underflow
675 if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
676 word0(adj) += (2*P+1)*Exp_msk1 - y;
677#else

--- 6 unchanged lines hidden (view full) ---

684 else
685 dval(rv) -= adj;
686 word0(rv) -= P*Exp_msk1;
687 goto cont;
688 }
689#endif /*Sudden_Underflow*/
690#endif /*Avoid_Underflow*/
691 adj *= ulp(dval(rv));
679 if (dsign)
692 if (dsign) {
693 if (word0(rv) == Big0 && word1(rv) == Big1)
694 goto ovfl;
680 dval(rv) += adj;
695 dval(rv) += adj;
696 }
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

--- 76 unchanged lines hidden (view full) ---

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;
697 else
698 dval(rv) -= adj;
699 goto cont;
700 }
701#endif /*Honor_FLT_ROUNDS*/
702
703 if (i < 0) {
704 /* Error is less than half an ulp -- check for

--- 76 unchanged lines hidden (view full) ---

781 /* accept rv */
782 break;
783 /* rv = smallest denormal */
784 goto undfl;
785 }
786 }
787#endif /*Avoid_Underflow*/
788 L = (word0(rv) & Exp_mask) - Exp_msk1;
773#endif /*Sudden_Underflow}*/
789#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 }

--- 203 unchanged lines hidden ---
790 word0(rv) = L | Bndry_mask1;
791 word1(rv) = 0xffffffff;
792#ifdef IBM
793 goto cont;
794#else
795 break;
796#endif
797 }

--- 203 unchanged lines hidden ---