]>
git.saurik.com Git - apple/libc.git/blob - gdtoa/FreeBSD/gdtoa-strtod.c
66a3baa2bc3dae7c572ea35dacb870da68f5b5f6
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^53 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.e
-256
53 #ifdef Honor_FLT_ROUNDS
54 #define Rounding rounding
55 #undef Check_FLT_ROUNDS
56 #define Check_FLT_ROUNDS
58 #define Rounding Flt_Rounds
64 (s00
, se
) CONST
char *s00
; char **se
;
66 (CONST
char *s00
, char **se
)
69 #ifdef Avoid_Underflow
72 int bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, dsign
,
73 e
, e1
, esign
, i
, j
, k
, nd
, nd0
, nf
, nz
, nz0
, sign
;
74 CONST
char *s
, *s0
, *s1
;
75 double aadj
, aadj1
, adj
, rv
, rv0
;
78 Bigint
*bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
;
80 int inexact
, oldinexact
;
82 #ifdef Honor_FLT_ROUNDS
86 sign
= nz0
= nz
= decpt
= 0;
88 for(s
= s00
;;s
++) switch(*s
) {
112 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
119 #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
121 switch(fegetround()) {
122 case FE_TOWARDZERO
: fpi1
.rounding
= 0; break;
123 case FE_UPWARD
: fpi1
.rounding
= 2; break;
124 case FE_DOWNWARD
: fpi1
.rounding
= 3;
129 switch((i
= gethex(&s
, &fpi1
, &exp
, &bb
, sign
)) & STRTOG_Retmask
) {
130 case STRTOG_NoNumber
:
137 copybits(bits
, fpi
.nbits
, bb
);
140 ULtod(((U
*)&rv
)->L
, bits
, exp
, i
);
153 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
160 if (c
== *localeconv()->decimal_point
)
168 for(; c
== '0'; c
= *++s
)
170 if (c
> '0' && c
<= '9') {
178 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
183 for(i
= 1; i
< nz
; i
++)
186 else if (nd
<= DBL_DIG
+ 1)
190 else if (nd
<= DBL_DIG
+ 1)
198 if (c
== 'e' || c
== 'E') {
199 if (!nd
&& !nz
&& !nz0
) {
210 if (c
>= '0' && c
<= '9') {
213 if (c
> '0' && c
<= '9') {
216 while((c
= *++s
) >= '0' && c
<= '9')
218 if (s
- s1
> 8 || L
> 19999)
219 /* Avoid confusion from exponents
220 * so large that e might overflow.
222 e
= 19999; /* safe for 16 bit ints */
237 /* Check for Nan and Infinity */
239 static FPI fpinan
= /* only 52 explicit bits */
240 { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
245 if (match(&s
,"nf")) {
247 if (!match(&s
,"inity"))
249 word0(rv
) = 0x7ff00000;
256 if (match(&s
, "an")) {
259 && hexnan(&s
, &fpinan
, bits
)
261 word0(rv
) = 0x7ff00000 | bits
[1];
266 word0(rv
) = NAN_WORD0
;
267 word1(rv
) = NAN_WORD1
;
274 #endif /* INFNAN_CHECK */
283 /* Now we have nd0 digits, starting at s0, followed by a
284 * decimal point, followed by nd-nd0 digits. The number we're
285 * after is the integer represented by those digits times
290 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
295 oldinexact
= get_inexact();
297 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
302 #ifndef Honor_FLT_ROUNDS
314 #ifdef Honor_FLT_ROUNDS
315 /* round correctly FLT_ROUNDS = 2 or 3 */
321 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
326 if (e
<= Ten_pmax
+ i
) {
327 /* A fancier test would sometimes let us do
328 * this for larger i values.
330 #ifdef Honor_FLT_ROUNDS
331 /* round correctly FLT_ROUNDS = 2 or 3 */
340 /* VAX exponent range is so narrow we must
341 * worry about overflow here...
344 word0(rv
) -= P
*Exp_msk1
;
345 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
346 if ((word0(rv
) & Exp_mask
)
347 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
349 word0(rv
) += P
*Exp_msk1
;
351 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
356 #ifndef Inaccurate_Divide
357 else if (e
>= -Ten_pmax
) {
358 #ifdef Honor_FLT_ROUNDS
359 /* round correctly FLT_ROUNDS = 2 or 3 */
365 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
376 oldinexact
= get_inexact();
378 #ifdef Avoid_Underflow
381 #ifdef Honor_FLT_ROUNDS
382 if ((rounding
= Flt_Rounds
) >= 2) {
384 rounding
= rounding
== 2 ? 0 : 2;
390 #endif /*IEEE_Arith*/
392 /* Get starting approximation = rv * 10**e1 */
395 if ( (i
= e1
& 15) !=0)
398 if (e1
> DBL_MAX_10_EXP
) {
403 /* Can't trust HUGE_VAL */
405 #ifdef Honor_FLT_ROUNDS
407 case 0: /* toward 0 */
408 case 3: /* toward -infinity */
413 word0(rv
) = Exp_mask
;
416 #else /*Honor_FLT_ROUNDS*/
417 word0(rv
) = Exp_mask
;
419 #endif /*Honor_FLT_ROUNDS*/
421 /* set overflow bit */
423 dval(rv0
) *= dval(rv0
);
428 #endif /*IEEE_Arith*/
434 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
436 dval(rv
) *= bigtens
[j
];
437 /* The last multiplication could overflow. */
438 word0(rv
) -= P
*Exp_msk1
;
439 dval(rv
) *= bigtens
[j
];
440 if ((z
= word0(rv
) & Exp_mask
)
441 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
443 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
444 /* set to largest number */
445 /* (Can't trust DBL_MAX) */
450 word0(rv
) += P
*Exp_msk1
;
455 if ( (i
= e1
& 15) !=0)
458 if (e1
>= 1 << n_bigtens
)
460 #ifdef Avoid_Underflow
463 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
465 dval(rv
) *= tinytens
[j
];
466 if (scale
&& (j
= 2*P
+ 1 - ((word0(rv
) & Exp_mask
)
467 >> Exp_shift
)) > 0) {
468 /* scaled rv is denormal; zap j low bits */
472 word0(rv
) = (P
+2)*Exp_msk1
;
474 word0(rv
) &= 0xffffffff << j
-32;
477 word1(rv
) &= 0xffffffff << j
;
480 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
482 dval(rv
) *= tinytens
[j
];
483 /* The last multiplication could underflow. */
484 dval(rv0
) = dval(rv
);
485 dval(rv
) *= tinytens
[j
];
487 dval(rv
) = 2.*dval(rv0
);
488 dval(rv
) *= tinytens
[j
];
500 #ifndef Avoid_Underflow
503 /* The refinement below will clean
504 * this approximation up.
511 /* Now the hard part -- adjusting rv to the correct value.*/
513 /* Put digits into bd: true value = bd * 10^e */
515 bd0
= s2b(s0
, nd0
, nd
, y
);
520 bb
= d2b(dval(rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
536 #ifdef Honor_FLT_ROUNDS
540 #ifdef Avoid_Underflow
542 i
= j
+ bbbits
- 1; /* logb(rv) */
543 if (i
< Emin
) /* denormal */
547 #else /*Avoid_Underflow*/
548 #ifdef Sudden_Underflow
550 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
554 #else /*Sudden_Underflow*/
556 i
= j
+ bbbits
- 1; /* logb(rv) */
557 if (i
< Emin
) /* denormal */
561 #endif /*Sudden_Underflow*/
562 #endif /*Avoid_Underflow*/
565 #ifdef Avoid_Underflow
568 i
= bb2
< bd2
? bb2
: bd2
;
577 bs
= pow5mult(bs
, bb5
);
583 bb
= lshift(bb
, bb2
);
585 bd
= pow5mult(bd
, bd5
);
587 bd
= lshift(bd
, bd2
);
589 bs
= lshift(bs
, bs2
);
590 delta
= diff(bb
, bd
);
594 #ifdef Honor_FLT_ROUNDS
597 /* Error is less than an ulp */
598 if (!delta
->x
[0] && delta
->wds
<= 1) {
614 && !(word0(rv
) & Frac_mask
)) {
615 y
= word0(rv
) & Exp_mask
;
616 #ifdef Avoid_Underflow
617 if (!scale
|| y
> 2*P
*Exp_msk1
)
622 delta
= lshift(delta
,Log2P
);
623 if (cmp(delta
, bs
) <= 0)
628 #ifdef Avoid_Underflow
629 if (scale
&& (y
= word0(rv
) & Exp_mask
)
631 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
633 #ifdef Sudden_Underflow
634 if ((word0(rv
) & Exp_mask
) <=
636 word0(rv
) += P
*Exp_msk1
;
637 dval(rv
) += adj
*ulp(dval(rv
));
638 word0(rv
) -= P
*Exp_msk1
;
641 #endif /*Sudden_Underflow*/
642 #endif /*Avoid_Underflow*/
643 dval(rv
) += adj
*ulp(dval(rv
));
647 adj
= ratio(delta
, bs
);
650 if (adj
<= 0x7ffffffe) {
651 /* adj = rounding ? ceil(adj) : floor(adj); */
654 if (!((rounding
>>1) ^ dsign
))
659 #ifdef Avoid_Underflow
660 if (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
661 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
663 #ifdef Sudden_Underflow
664 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
665 word0(rv
) += P
*Exp_msk1
;
666 adj
*= ulp(dval(rv
));
671 word0(rv
) -= P
*Exp_msk1
;
674 #endif /*Sudden_Underflow*/
675 #endif /*Avoid_Underflow*/
676 adj
*= ulp(dval(rv
));
683 #endif /*Honor_FLT_ROUNDS*/
686 /* Error is less than half an ulp -- check for
687 * special case of mantissa a power of two.
689 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
691 #ifdef Avoid_Underflow
692 || (word0(rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
694 || (word0(rv
) & Exp_mask
) <= Exp_msk1
699 if (!delta
->x
[0] && delta
->wds
<= 1)
704 if (!delta
->x
[0] && delta
->wds
<= 1) {
711 delta
= lshift(delta
,Log2P
);
712 if (cmp(delta
, bs
) > 0)
717 /* exactly half-way between */
719 if ((word0(rv
) & Bndry_mask1
) == Bndry_mask1
721 #ifdef Avoid_Underflow
722 (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
723 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
726 /*boundary case -- increment exponent*/
727 word0(rv
) = (word0(rv
) & Exp_mask
)
734 #ifdef Avoid_Underflow
740 else if (!(word0(rv
) & Bndry_mask
) && !word1(rv
)) {
742 /* boundary case -- decrement exponent */
743 #ifdef Sudden_Underflow /*{{*/
744 L
= word0(rv
) & Exp_mask
;
748 #ifdef Avoid_Underflow
749 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
752 #endif /*Avoid_Underflow*/
756 #else /*Sudden_Underflow}{*/
757 #ifdef Avoid_Underflow
759 L
= word0(rv
) & Exp_mask
;
760 if (L
<= (2*P
+1)*Exp_msk1
) {
761 if (L
> (P
+2)*Exp_msk1
)
765 /* rv = smallest denormal */
769 #endif /*Avoid_Underflow*/
770 L
= (word0(rv
) & Exp_mask
) - Exp_msk1
;
771 #endif /*Sudden_Underflow}*/
772 word0(rv
) = L
| Bndry_mask1
;
773 word1(rv
) = 0xffffffff;
781 if (!(word1(rv
) & LSB
))
785 dval(rv
) += ulp(dval(rv
));
788 dval(rv
) -= ulp(dval(rv
));
789 #ifndef Sudden_Underflow
794 #ifdef Avoid_Underflow
800 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
803 else if (word1(rv
) || word0(rv
) & Bndry_mask
) {
804 #ifndef Sudden_Underflow
805 if (word1(rv
) == Tiny1
&& !word0(rv
))
812 /* special case -- power of FLT_RADIX to be */
813 /* rounded down... */
815 if (aadj
< 2./FLT_RADIX
)
824 aadj1
= dsign
? aadj
: -aadj
;
825 #ifdef Check_FLT_ROUNDS
827 case 2: /* towards +infinity */
830 case 0: /* towards 0 */
831 case 3: /* towards -infinity */
837 #endif /*Check_FLT_ROUNDS*/
839 y
= word0(rv
) & Exp_mask
;
841 /* Check for overflow */
843 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
844 dval(rv0
) = dval(rv
);
845 word0(rv
) -= P
*Exp_msk1
;
846 adj
= aadj1
* ulp(dval(rv
));
848 if ((word0(rv
) & Exp_mask
) >=
849 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
850 if (word0(rv0
) == Big0
&& word1(rv0
) == Big1
)
857 word0(rv
) += P
*Exp_msk1
;
860 #ifdef Avoid_Underflow
861 if (scale
&& y
<= 2*P
*Exp_msk1
) {
862 if (aadj
<= 0x7fffffff) {
866 aadj1
= dsign
? aadj
: -aadj
;
868 word0(aadj1
) += (2*P
+1)*Exp_msk1
- y
;
870 adj
= aadj1
* ulp(dval(rv
));
873 #ifdef Sudden_Underflow
874 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
875 dval(rv0
) = dval(rv
);
876 word0(rv
) += P
*Exp_msk1
;
877 adj
= aadj1
* ulp(dval(rv
));
880 if ((word0(rv
) & Exp_mask
) < P
*Exp_msk1
)
882 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
)
885 if (word0(rv0
) == Tiny0
886 && word1(rv0
) == Tiny1
)
893 word0(rv
) -= P
*Exp_msk1
;
896 adj
= aadj1
* ulp(dval(rv
));
899 #else /*Sudden_Underflow*/
900 /* Compute adj so that the IEEE rounding rules will
901 * correctly round rv + adj in some half-way cases.
902 * If rv * ulp(rv) is denormalized (i.e.,
903 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
904 * trouble from bits lost to denormalization;
905 * example: 1.2e-307 .
907 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
908 aadj1
= (double)(int)(aadj
+ 0.5);
912 adj
= aadj1
* ulp(dval(rv
));
914 #endif /*Sudden_Underflow*/
915 #endif /*Avoid_Underflow*/
917 z
= word0(rv
) & Exp_mask
;
919 #ifdef Avoid_Underflow
923 /* Can we stop now? */
926 /* The tolerances below are conservative. */
927 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
) {
928 if (aadj
< .4999999 || aadj
> .5000001)
931 else if (aadj
< .4999999/FLT_RADIX
)
944 word0(rv0
) = Exp_1
+ (70 << Exp_shift
);
949 else if (!oldinexact
)
952 #ifdef Avoid_Underflow
954 word0(rv0
) = Exp_1
- 2*P
*Exp_msk1
;
956 dval(rv
) *= dval(rv0
);
958 /* try to avoid the bug of testing an 8087 register value */
959 if (word0(rv
) == 0 && word1(rv
) == 0)
963 #endif /* Avoid_Underflow */
965 if (inexact
&& !(word0(rv
) & Exp_mask
)) {
966 /* set underflow bit */
968 dval(rv0
) *= dval(rv0
);
980 return sign
? -dval(rv
) : dval(rv
);