]>
git.saurik.com Git - apple/libc.git/blob - gdtoa/FreeBSD/gdtoa-strtod.c
bc06bfe1c1bbe61ec300c5130eba9384790fa522
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 "."). */
40 #define Avoid_Underflow
42 /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
43 /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
44 static CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128,
45 9007199254740992.e
-256
50 #ifdef Honor_FLT_ROUNDS
51 #define Rounding rounding
52 #undef Check_FLT_ROUNDS
53 #define Check_FLT_ROUNDS
55 #define Rounding Flt_Rounds
61 (s00
, se
) CONST
char *s00
; char **se
;
63 (CONST
char *s00
, char **se
)
66 #ifdef Avoid_Underflow
69 int bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, dsign
,
70 e
, e1
, esign
, i
, j
, k
, nd
, nd0
, nf
, nz
, nz0
, sign
;
71 CONST
char *s
, *s0
, *s1
;
72 double aadj
, aadj1
, adj
, rv
, rv0
;
75 Bigint
*bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
;
77 int inexact
, oldinexact
;
79 #ifdef Honor_FLT_ROUNDS
83 sign
= nz0
= nz
= decpt
= 0;
85 for(s
= s00
;;s
++) switch(*s
) {
109 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
115 switch((i
= gethex(&s
, &fpi
, &exp
, &bb
, sign
)) & STRTOG_Retmask
) {
116 case STRTOG_NoNumber
:
123 copybits(bits
, fpi
.nbits
, bb
);
126 ULtod(((U
*)&rv
)->L
, bits
, exp
, i
);
139 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
146 if (c
== *localeconv()->decimal_point
)
154 for(; c
== '0'; c
= *++s
)
156 if (c
> '0' && c
<= '9') {
164 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
169 for(i
= 1; i
< nz
; i
++)
172 else if (nd
<= DBL_DIG
+ 1)
176 else if (nd
<= DBL_DIG
+ 1)
184 if (c
== 'e' || c
== 'E') {
185 if (!nd
&& !nz
&& !nz0
) {
196 if (c
>= '0' && c
<= '9') {
199 if (c
> '0' && c
<= '9') {
202 while((c
= *++s
) >= '0' && c
<= '9')
204 if (s
- s1
> 8 || L
> 19999)
205 /* Avoid confusion from exponents
206 * so large that e might overflow.
208 e
= 19999; /* safe for 16 bit ints */
223 /* Check for Nan and Infinity */
225 static FPI fpinan
= /* only 52 explicit bits */
226 { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
231 if (match(&s
,"nf")) {
233 if (!match(&s
,"inity"))
235 word0(rv
) = 0x7ff00000;
242 if (match(&s
, "an")) {
245 && hexnan(&s
, &fpinan
, bits
)
247 word0(rv
) = 0x7ff00000 | bits
[1];
252 word0(rv
) = NAN_WORD0
;
253 word1(rv
) = NAN_WORD1
;
260 #endif /* INFNAN_CHECK */
269 /* Now we have nd0 digits, starting at s0, followed by a
270 * decimal point, followed by nd-nd0 digits. The number we're
271 * after is the integer represented by those digits times
276 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
281 oldinexact
= get_inexact();
283 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
288 #ifndef Honor_FLT_ROUNDS
300 #ifdef Honor_FLT_ROUNDS
301 /* round correctly FLT_ROUNDS = 2 or 3 */
307 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
312 if (e
<= Ten_pmax
+ i
) {
313 /* A fancier test would sometimes let us do
314 * this for larger i values.
316 #ifdef Honor_FLT_ROUNDS
317 /* round correctly FLT_ROUNDS = 2 or 3 */
326 /* VAX exponent range is so narrow we must
327 * worry about overflow here...
330 word0(rv
) -= P
*Exp_msk1
;
331 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
332 if ((word0(rv
) & Exp_mask
)
333 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
335 word0(rv
) += P
*Exp_msk1
;
337 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
342 #ifndef Inaccurate_Divide
343 else if (e
>= -Ten_pmax
) {
344 #ifdef Honor_FLT_ROUNDS
345 /* round correctly FLT_ROUNDS = 2 or 3 */
351 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
362 oldinexact
= get_inexact();
364 #ifdef Avoid_Underflow
367 #ifdef Honor_FLT_ROUNDS
368 if ((rounding
= Flt_Rounds
) >= 2) {
370 rounding
= rounding
== 2 ? 0 : 2;
376 #endif /*IEEE_Arith*/
378 /* Get starting approximation = rv * 10**e1 */
381 if ( (i
= e1
& 15) !=0)
384 if (e1
> DBL_MAX_10_EXP
) {
389 /* Can't trust HUGE_VAL */
391 #ifdef Honor_FLT_ROUNDS
393 case 0: /* toward 0 */
394 case 3: /* toward -infinity */
399 word0(rv
) = Exp_mask
;
402 #else /*Honor_FLT_ROUNDS*/
403 word0(rv
) = Exp_mask
;
405 #endif /*Honor_FLT_ROUNDS*/
407 /* set overflow bit */
409 dval(rv0
) *= dval(rv0
);
414 #endif /*IEEE_Arith*/
420 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
422 dval(rv
) *= bigtens
[j
];
423 /* The last multiplication could overflow. */
424 word0(rv
) -= P
*Exp_msk1
;
425 dval(rv
) *= bigtens
[j
];
426 if ((z
= word0(rv
) & Exp_mask
)
427 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
429 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
430 /* set to largest number */
431 /* (Can't trust DBL_MAX) */
436 word0(rv
) += P
*Exp_msk1
;
441 if ( (i
= e1
& 15) !=0)
444 if (e1
>= 1 << n_bigtens
)
446 #ifdef Avoid_Underflow
449 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
451 dval(rv
) *= tinytens
[j
];
452 if (scale
&& (j
= 2*P
+ 1 - ((word0(rv
) & Exp_mask
)
453 >> Exp_shift
)) > 0) {
454 /* scaled rv is denormal; zap j low bits */
458 word0(rv
) = (P
+2)*Exp_msk1
;
460 word0(rv
) &= 0xffffffff << j
-32;
463 word1(rv
) &= 0xffffffff << j
;
466 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
468 dval(rv
) *= tinytens
[j
];
469 /* The last multiplication could underflow. */
470 dval(rv0
) = dval(rv
);
471 dval(rv
) *= tinytens
[j
];
473 dval(rv
) = 2.*dval(rv0
);
474 dval(rv
) *= tinytens
[j
];
486 #ifndef Avoid_Underflow
489 /* The refinement below will clean
490 * this approximation up.
497 /* Now the hard part -- adjusting rv to the correct value.*/
499 /* Put digits into bd: true value = bd * 10^e */
501 bd0
= s2b(s0
, nd0
, nd
, y
);
506 bb
= d2b(dval(rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
522 #ifdef Honor_FLT_ROUNDS
526 #ifdef Avoid_Underflow
528 i
= j
+ bbbits
- 1; /* logb(rv) */
529 if (i
< Emin
) /* denormal */
533 #else /*Avoid_Underflow*/
534 #ifdef Sudden_Underflow
536 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
540 #else /*Sudden_Underflow*/
542 i
= j
+ bbbits
- 1; /* logb(rv) */
543 if (i
< Emin
) /* denormal */
547 #endif /*Sudden_Underflow*/
548 #endif /*Avoid_Underflow*/
551 #ifdef Avoid_Underflow
554 i
= bb2
< bd2
? bb2
: bd2
;
563 bs
= pow5mult(bs
, bb5
);
569 bb
= lshift(bb
, bb2
);
571 bd
= pow5mult(bd
, bd5
);
573 bd
= lshift(bd
, bd2
);
575 bs
= lshift(bs
, bs2
);
576 delta
= diff(bb
, bd
);
580 #ifdef Honor_FLT_ROUNDS
583 /* Error is less than an ulp */
584 if (!delta
->x
[0] && delta
->wds
<= 1) {
600 && !(word0(rv
) & Frac_mask
)) {
601 y
= word0(rv
) & Exp_mask
;
602 #ifdef Avoid_Underflow
603 if (!scale
|| y
> 2*P
*Exp_msk1
)
608 delta
= lshift(delta
,Log2P
);
609 if (cmp(delta
, bs
) <= 0)
614 #ifdef Avoid_Underflow
615 if (scale
&& (y
= word0(rv
) & Exp_mask
)
617 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
619 #ifdef Sudden_Underflow
620 if ((word0(rv
) & Exp_mask
) <=
622 word0(rv
) += P
*Exp_msk1
;
623 dval(rv
) += adj
*ulp(dval(rv
));
624 word0(rv
) -= P
*Exp_msk1
;
627 #endif /*Sudden_Underflow*/
628 #endif /*Avoid_Underflow*/
629 dval(rv
) += adj
*ulp(dval(rv
));
633 adj
= ratio(delta
, bs
);
636 if (adj
<= 0x7ffffffe) {
637 /* adj = rounding ? ceil(adj) : floor(adj); */
640 if (!((rounding
>>1) ^ dsign
))
645 #ifdef Avoid_Underflow
646 if (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
647 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
649 #ifdef Sudden_Underflow
650 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
651 word0(rv
) += P
*Exp_msk1
;
652 adj
*= ulp(dval(rv
));
657 word0(rv
) -= P
*Exp_msk1
;
660 #endif /*Sudden_Underflow*/
661 #endif /*Avoid_Underflow*/
662 adj
*= ulp(dval(rv
));
669 #endif /*Honor_FLT_ROUNDS*/
672 /* Error is less than half an ulp -- check for
673 * special case of mantissa a power of two.
675 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
677 #ifdef Avoid_Underflow
678 || (word0(rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
680 || (word0(rv
) & Exp_mask
) <= Exp_msk1
685 if (!delta
->x
[0] && delta
->wds
<= 1)
690 if (!delta
->x
[0] && delta
->wds
<= 1) {
697 delta
= lshift(delta
,Log2P
);
698 if (cmp(delta
, bs
) > 0)
703 /* exactly half-way between */
705 if ((word0(rv
) & Bndry_mask1
) == Bndry_mask1
707 #ifdef Avoid_Underflow
708 (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
709 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
712 /*boundary case -- increment exponent*/
713 word0(rv
) = (word0(rv
) & Exp_mask
)
720 #ifdef Avoid_Underflow
726 else if (!(word0(rv
) & Bndry_mask
) && !word1(rv
)) {
728 /* boundary case -- decrement exponent */
729 #ifdef Sudden_Underflow /*{{*/
730 L
= word0(rv
) & Exp_mask
;
734 #ifdef Avoid_Underflow
735 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
738 #endif /*Avoid_Underflow*/
742 #else /*Sudden_Underflow}{*/
743 #ifdef Avoid_Underflow
745 L
= word0(rv
) & Exp_mask
;
746 if (L
<= (2*P
+1)*Exp_msk1
) {
747 if (L
> (P
+2)*Exp_msk1
)
751 /* rv = smallest denormal */
755 #endif /*Avoid_Underflow*/
756 L
= (word0(rv
) & Exp_mask
) - Exp_msk1
;
757 #endif /*Sudden_Underflow}*/
758 word0(rv
) = L
| Bndry_mask1
;
759 word1(rv
) = 0xffffffff;
767 if (!(word1(rv
) & LSB
))
771 dval(rv
) += ulp(dval(rv
));
774 dval(rv
) -= ulp(dval(rv
));
775 #ifndef Sudden_Underflow
780 #ifdef Avoid_Underflow
786 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
789 else if (word1(rv
) || word0(rv
) & Bndry_mask
) {
790 #ifndef Sudden_Underflow
791 if (word1(rv
) == Tiny1
&& !word0(rv
))
798 /* special case -- power of FLT_RADIX to be */
799 /* rounded down... */
801 if (aadj
< 2./FLT_RADIX
)
810 aadj1
= dsign
? aadj
: -aadj
;
811 #ifdef Check_FLT_ROUNDS
813 case 2: /* towards +infinity */
816 case 0: /* towards 0 */
817 case 3: /* towards -infinity */
823 #endif /*Check_FLT_ROUNDS*/
825 y
= word0(rv
) & Exp_mask
;
827 /* Check for overflow */
829 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
830 dval(rv0
) = dval(rv
);
831 word0(rv
) -= P
*Exp_msk1
;
832 adj
= aadj1
* ulp(dval(rv
));
834 if ((word0(rv
) & Exp_mask
) >=
835 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
836 if (word0(rv0
) == Big0
&& word1(rv0
) == Big1
)
843 word0(rv
) += P
*Exp_msk1
;
846 #ifdef Avoid_Underflow
847 if (scale
&& y
<= 2*P
*Exp_msk1
) {
848 if (aadj
<= 0x7fffffff) {
852 aadj1
= dsign
? aadj
: -aadj
;
854 word0(aadj1
) += (2*P
+1)*Exp_msk1
- y
;
856 adj
= aadj1
* ulp(dval(rv
));
859 #ifdef Sudden_Underflow
860 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
861 dval(rv0
) = dval(rv
);
862 word0(rv
) += P
*Exp_msk1
;
863 adj
= aadj1
* ulp(dval(rv
));
866 if ((word0(rv
) & Exp_mask
) < P
*Exp_msk1
)
868 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
)
871 if (word0(rv0
) == Tiny0
872 && word1(rv0
) == Tiny1
)
879 word0(rv
) -= P
*Exp_msk1
;
882 adj
= aadj1
* ulp(dval(rv
));
885 #else /*Sudden_Underflow*/
886 /* Compute adj so that the IEEE rounding rules will
887 * correctly round rv + adj in some half-way cases.
888 * If rv * ulp(rv) is denormalized (i.e.,
889 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
890 * trouble from bits lost to denormalization;
891 * example: 1.2e-307 .
893 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
894 aadj1
= (double)(int)(aadj
+ 0.5);
898 adj
= aadj1
* ulp(dval(rv
));
900 #endif /*Sudden_Underflow*/
901 #endif /*Avoid_Underflow*/
903 z
= word0(rv
) & Exp_mask
;
905 #ifdef Avoid_Underflow
909 /* Can we stop now? */
912 /* The tolerances below are conservative. */
913 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
) {
914 if (aadj
< .4999999 || aadj
> .5000001)
917 else if (aadj
< .4999999/FLT_RADIX
)
930 word0(rv0
) = Exp_1
+ (70 << Exp_shift
);
935 else if (!oldinexact
)
938 #ifdef Avoid_Underflow
940 word0(rv0
) = Exp_1
- 2*P
*Exp_msk1
;
942 dval(rv
) *= dval(rv0
);
944 /* try to avoid the bug of testing an 8087 register value */
945 if (word0(rv
) == 0 && word1(rv
) == 0)
949 #endif /* Avoid_Underflow */
951 if (inexact
&& !(word0(rv
) & Exp_mask
)) {
952 /* set underflow bit */
954 dval(rv0
) *= dval(rv0
);
966 return sign
? -dval(rv
) : dval(rv
);