]>
git.saurik.com Git - apple/libc.git/blob - gdtoa/FreeBSD/gdtoa-strtod.c
1 /****************************************************************
3 The author of this software is David M. Gay.
5 Copyright (C) 1998-2001 by Lucent Technologies
8 Permission to use, copy, modify, and distribute this software and
9 its documentation for any purpose and without fee is hereby
10 granted, provided that the above copyright notice appear in all
11 copies and that both that the copyright notice and this
12 permission notice and warranty disclaimer appear in supporting
13 documentation, and that the name of Lucent or any of its entities
14 not be used in advertising or publicity pertaining to
15 distribution of the software without specific, written prior
18 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
27 ****************************************************************/
29 /* Please send bug reports to David M. Gay (dmg at acm dot org,
30 * with " at " changed at "@" and " dot " changed to "."). */
43 #define Avoid_Underflow
45 /* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */
46 /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
47 static CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128,
48 9007199254740992.*9007199254740992.e
-256
53 #ifdef Honor_FLT_ROUNDS
54 #undef Check_FLT_ROUNDS
55 #define Check_FLT_ROUNDS
57 #define Rounding Flt_Rounds
63 (s00
, se
) CONST
char *s00
; char **se
;
65 (CONST
char *s00
, char **se
)
68 #ifdef Avoid_Underflow
71 int bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, dsign
,
72 e
, e1
, esign
, i
, j
, k
, nd
, nd0
, nf
, nz
, nz0
, sign
;
73 CONST
char *s
, *s0
, *s1
;
74 double aadj
, aadj1
, adj
, rv
, rv0
;
77 Bigint
*bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
;
79 int inexact
, oldinexact
;
82 #ifdef NO_LOCALE_CACHE
83 char *decimalpoint
= localeconv()->decimal_point
;
86 static char *decimalpoint_cache
;
87 if (!(s0
= decimalpoint_cache
)) {
88 s0
= localeconv()->decimal_point
;
89 if ((decimalpoint_cache
= (char*)malloc(strlen(s0
) + 1))) {
90 strcpy(decimalpoint_cache
, s0
);
91 s0
= decimalpoint_cache
;
94 decimalpoint
= (char*)s0
;
97 #ifdef Honor_FLT_ROUNDS /*{*/
99 #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
100 Rounding
= Flt_Rounds
;
103 switch(fegetround()) {
104 case FE_TOWARDZERO
: Rounding
= 0; break;
105 case FE_UPWARD
: Rounding
= 2; break;
106 case FE_DOWNWARD
: Rounding
= 3;
111 sign
= nz0
= nz
= decpt
= 0;
113 for(s
= s00
;;s
++) switch(*s
) {
135 #ifndef NO_HEX_FP /*{*/
137 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
144 #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) /*{{*/
146 #ifdef Honor_FLT_ROUNDS /*{{*/
147 fpi1
.rounding
= Rounding
;
149 switch(fegetround()) {
150 case FE_TOWARDZERO
: fpi1
.rounding
= 0; break;
151 case FE_UPWARD
: fpi1
.rounding
= 2; break;
152 case FE_DOWNWARD
: fpi1
.rounding
= 3;
158 switch((i
= gethex(&s
, &fpi1
, &exp
, &bb
, sign
)) & STRTOG_Retmask
) {
159 case STRTOG_NoNumber
:
166 copybits(bits
, fpi
.nbits
, bb
);
169 ULtod(((U
*)&rv
)->L
, bits
, exp
, i
);
182 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
189 if (c
== *decimalpoint
) {
190 for(i
= 1; decimalpoint
[i
]; ++i
)
191 if (s
[i
] != decimalpoint
[i
])
201 for(; c
== '0'; c
= *++s
)
203 if (c
> '0' && c
<= '9') {
211 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
216 for(i
= 1; i
< nz
; i
++)
219 else if (nd
<= DBL_DIG
+ 1)
223 else if (nd
<= DBL_DIG
+ 1)
231 if (c
== 'e' || c
== 'E') {
232 if (!nd
&& !nz
&& !nz0
) {
243 if (c
>= '0' && c
<= '9') {
246 if (c
> '0' && c
<= '9') {
249 while((c
= *++s
) >= '0' && c
<= '9')
251 if (s
- s1
> 8 || L
> 19999)
252 /* Avoid confusion from exponents
253 * so large that e might overflow.
255 e
= 19999; /* safe for 16 bit ints */
270 /* Check for Nan and Infinity */
272 static FPI fpinan
= /* only 52 explicit bits */
273 { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
278 if (match(&s
,"nf")) {
280 if (!match(&s
,"inity"))
282 word0(rv
) = 0x7ff00000;
289 if (match(&s
, "an")) {
292 && hexnan(&s
, &fpinan
, bits
)
294 word0(rv
) = 0x7ff00000 | bits
[1];
299 word0(rv
) = NAN_WORD0
;
300 word1(rv
) = NAN_WORD1
;
307 #endif /* INFNAN_CHECK */
316 /* Now we have nd0 digits, starting at s0, followed by a
317 * decimal point, followed by nd-nd0 digits. The number we're
318 * after is the integer represented by those digits times
323 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
328 oldinexact
= get_inexact();
330 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
335 #ifndef Honor_FLT_ROUNDS
347 #ifdef Honor_FLT_ROUNDS
348 /* round correctly FLT_ROUNDS = 2 or 3 */
354 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
359 if (e
<= Ten_pmax
+ i
) {
360 /* A fancier test would sometimes let us do
361 * this for larger i values.
363 #ifdef Honor_FLT_ROUNDS
364 /* round correctly FLT_ROUNDS = 2 or 3 */
373 /* VAX exponent range is so narrow we must
374 * worry about overflow here...
377 word0(rv
) -= P
*Exp_msk1
;
378 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
379 if ((word0(rv
) & Exp_mask
)
380 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
382 word0(rv
) += P
*Exp_msk1
;
384 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
389 #ifndef Inaccurate_Divide
390 else if (e
>= -Ten_pmax
) {
391 #ifdef Honor_FLT_ROUNDS
392 /* round correctly FLT_ROUNDS = 2 or 3 */
398 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
409 oldinexact
= get_inexact();
411 #ifdef Avoid_Underflow
414 #ifdef Honor_FLT_ROUNDS
417 Rounding
= Rounding
== 2 ? 0 : 2;
423 #endif /*IEEE_Arith*/
425 /* Get starting approximation = rv * 10**e1 */
428 if ( (i
= e1
& 15) !=0)
431 if (e1
> DBL_MAX_10_EXP
) {
436 /* Can't trust HUGE_VAL */
438 #ifdef Honor_FLT_ROUNDS
440 case 0: /* toward 0 */
441 case 3: /* toward -infinity */
446 word0(rv
) = Exp_mask
;
449 #else /*Honor_FLT_ROUNDS*/
450 word0(rv
) = Exp_mask
;
452 #endif /*Honor_FLT_ROUNDS*/
454 /* set overflow bit */
456 dval(rv0
) *= dval(rv0
);
461 #endif /*IEEE_Arith*/
467 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
469 dval(rv
) *= bigtens
[j
];
470 /* The last multiplication could overflow. */
471 word0(rv
) -= P
*Exp_msk1
;
472 dval(rv
) *= bigtens
[j
];
473 if ((z
= word0(rv
) & Exp_mask
)
474 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
476 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
477 /* set to largest number */
478 /* (Can't trust DBL_MAX) */
483 word0(rv
) += P
*Exp_msk1
;
488 if ( (i
= e1
& 15) !=0)
491 if (e1
>= 1 << n_bigtens
)
493 #ifdef Avoid_Underflow
496 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
498 dval(rv
) *= tinytens
[j
];
499 if (scale
&& (j
= 2*P
+ 1 - ((word0(rv
) & Exp_mask
)
500 >> Exp_shift
)) > 0) {
501 /* scaled rv is denormal; zap j low bits */
505 word0(rv
) = (P
+2)*Exp_msk1
;
507 word0(rv
) &= 0xffffffff << j
-32;
510 word1(rv
) &= 0xffffffff << j
;
513 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
515 dval(rv
) *= tinytens
[j
];
516 /* The last multiplication could underflow. */
517 dval(rv0
) = dval(rv
);
518 dval(rv
) *= tinytens
[j
];
520 dval(rv
) = 2.*dval(rv0
);
521 dval(rv
) *= tinytens
[j
];
533 #ifndef Avoid_Underflow
536 /* The refinement below will clean
537 * this approximation up.
544 /* Now the hard part -- adjusting rv to the correct value.*/
546 /* Put digits into bd: true value = bd * 10^e */
548 bd0
= s2b(s0
, nd0
, nd
, y
);
553 bb
= d2b(dval(rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
569 #ifdef Honor_FLT_ROUNDS
573 #ifdef Avoid_Underflow
575 i
= j
+ bbbits
- 1; /* logb(rv) */
576 if (i
< Emin
) /* denormal */
580 #else /*Avoid_Underflow*/
581 #ifdef Sudden_Underflow
583 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
587 #else /*Sudden_Underflow*/
589 i
= j
+ bbbits
- 1; /* logb(rv) */
590 if (i
< Emin
) /* denormal */
594 #endif /*Sudden_Underflow*/
595 #endif /*Avoid_Underflow*/
598 #ifdef Avoid_Underflow
601 i
= bb2
< bd2
? bb2
: bd2
;
610 bs
= pow5mult(bs
, bb5
);
616 bb
= lshift(bb
, bb2
);
618 bd
= pow5mult(bd
, bd5
);
620 bd
= lshift(bd
, bd2
);
622 bs
= lshift(bs
, bs2
);
623 delta
= diff(bb
, bd
);
627 #ifdef Honor_FLT_ROUNDS
630 /* Error is less than an ulp */
631 if (!delta
->x
[0] && delta
->wds
<= 1) {
647 && !(word0(rv
) & Frac_mask
)) {
648 y
= word0(rv
) & Exp_mask
;
649 #ifdef Avoid_Underflow
650 if (!scale
|| y
> 2*P
*Exp_msk1
)
655 delta
= lshift(delta
,Log2P
);
656 if (cmp(delta
, bs
) <= 0)
661 #ifdef Avoid_Underflow
662 if (scale
&& (y
= word0(rv
) & Exp_mask
)
664 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
666 #ifdef Sudden_Underflow
667 if ((word0(rv
) & Exp_mask
) <=
669 word0(rv
) += P
*Exp_msk1
;
670 dval(rv
) += adj
*ulp(dval(rv
));
671 word0(rv
) -= P
*Exp_msk1
;
674 #endif /*Sudden_Underflow*/
675 #endif /*Avoid_Underflow*/
676 dval(rv
) += adj
*ulp(dval(rv
));
680 adj
= ratio(delta
, bs
);
683 if (adj
<= 0x7ffffffe) {
684 /* adj = Rounding ? ceil(adj) : floor(adj); */
687 if (!((Rounding
>>1) ^ dsign
))
692 #ifdef Avoid_Underflow
693 if (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
694 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
696 #ifdef Sudden_Underflow
697 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
698 word0(rv
) += P
*Exp_msk1
;
699 adj
*= ulp(dval(rv
));
704 word0(rv
) -= P
*Exp_msk1
;
707 #endif /*Sudden_Underflow*/
708 #endif /*Avoid_Underflow*/
709 adj
*= ulp(dval(rv
));
711 if (word0(rv
) == Big0
&& word1(rv
) == Big1
)
719 #endif /*Honor_FLT_ROUNDS*/
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
727 #ifdef Avoid_Underflow
728 || (word0(rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
730 || (word0(rv
) & Exp_mask
) <= Exp_msk1
735 if (!delta
->x
[0] && delta
->wds
<= 1)
740 if (!delta
->x
[0] && delta
->wds
<= 1) {
747 delta
= lshift(delta
,Log2P
);
748 if (cmp(delta
, bs
) > 0)
753 /* exactly half-way between */
755 if ((word0(rv
) & Bndry_mask1
) == Bndry_mask1
757 #ifdef Avoid_Underflow
758 (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
759 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
762 /*boundary case -- increment exponent*/
763 word0(rv
) = (word0(rv
) & Exp_mask
)
770 #ifdef Avoid_Underflow
776 else if (!(word0(rv
) & Bndry_mask
) && !word1(rv
)) {
778 /* boundary case -- decrement exponent */
779 #ifdef Sudden_Underflow /*{{*/
780 L
= word0(rv
) & Exp_mask
;
784 #ifdef Avoid_Underflow
785 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
788 #endif /*Avoid_Underflow*/
792 #else /*Sudden_Underflow}{*/
793 #ifdef Avoid_Underflow
795 L
= word0(rv
) & Exp_mask
;
796 if (L
<= (2*P
+1)*Exp_msk1
) {
797 if (L
> (P
+2)*Exp_msk1
)
801 /* rv = smallest denormal */
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;
817 if (!(word1(rv
) & LSB
))
821 dval(rv
) += ulp(dval(rv
));
824 dval(rv
) -= ulp(dval(rv
));
825 #ifndef Sudden_Underflow
830 #ifdef Avoid_Underflow
836 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
839 else if (word1(rv
) || word0(rv
) & Bndry_mask
) {
840 #ifndef Sudden_Underflow
841 if (word1(rv
) == Tiny1
&& !word0(rv
))
848 /* special case -- power of FLT_RADIX to be */
849 /* rounded down... */
851 if (aadj
< 2./FLT_RADIX
)
860 aadj1
= dsign
? aadj
: -aadj
;
861 #ifdef Check_FLT_ROUNDS
863 case 2: /* towards +infinity */
866 case 0: /* towards 0 */
867 case 3: /* towards -infinity */
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
));
884 if ((word0(rv
) & Exp_mask
) >=
885 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
886 if (word0(rv0
) == Big0
&& word1(rv0
) == Big1
)
893 word0(rv
) += P
*Exp_msk1
;
896 #ifdef Avoid_Underflow
897 if (scale
&& y
<= 2*P
*Exp_msk1
) {
898 if (aadj
<= 0x7fffffff) {
902 aadj1
= dsign
? aadj
: -aadj
;
904 word0(aadj1
) += (2*P
+1)*Exp_msk1
- y
;
906 adj
= aadj1
* ulp(dval(rv
));
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
));
916 if ((word0(rv
) & Exp_mask
) < P
*Exp_msk1
)
918 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
)
921 if (word0(rv0
) == Tiny0
922 && word1(rv0
) == Tiny1
)
929 word0(rv
) -= P
*Exp_msk1
;
932 adj
= aadj1
* ulp(dval(rv
));
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);
948 adj
= aadj1
* ulp(dval(rv
));
950 #endif /*Sudden_Underflow*/
951 #endif /*Avoid_Underflow*/
953 z
= word0(rv
) & Exp_mask
;
955 #ifdef Avoid_Underflow
959 /* Can we stop now? */
962 /* The tolerances below are conservative. */
963 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
) {
964 if (aadj
< .4999999 || aadj
> .5000001)
967 else if (aadj
< .4999999/FLT_RADIX
)
980 word0(rv0
) = Exp_1
+ (70 << Exp_shift
);
985 else if (!oldinexact
)
988 #ifdef Avoid_Underflow
990 word0(rv0
) = Exp_1
- 2*P
*Exp_msk1
;
992 dval(rv
) *= dval(rv0
);
994 /* try to avoid the bug of testing an 8087 register value */
996 if (!(word0(rv
) & Exp_mask
))
998 if (word0(rv
) == 0 && word1(rv
) == 0)
1003 #endif /* Avoid_Underflow */
1005 if (inexact
&& !(word0(rv
) & Exp_mask
)) {
1006 /* set underflow bit */
1008 dval(rv0
) *= dval(rv0
);
1020 return sign
? -dval(rv
) : dval(rv
);