]>
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
;
76 U adj
, aadj1
, rv
, rv0
;
78 Bigint
*bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
;
80 int inexact
, oldinexact
;
82 #ifdef USE_LOCALE /*{{*/
83 #ifdef NO_LOCALE_CACHE
84 char *decimalpoint
= localeconv()->decimal_point
;
85 int dplen
= strlen(decimalpoint
);
88 static char *decimalpoint_cache
;
90 if (!(s0
= decimalpoint_cache
)) {
91 s0
= localeconv()->decimal_point
;
92 if ((decimalpoint_cache
= (char*)MALLOC(strlen(s0
) + 1))) {
93 strcpy(decimalpoint_cache
, s0
);
94 s0
= decimalpoint_cache
;
98 decimalpoint
= (char*)s0
;
99 #endif /*NO_LOCALE_CACHE*/
100 #else /*USE_LOCALE}{*/
102 #endif /*USE_LOCALE}}*/
104 #ifdef Honor_FLT_ROUNDS /*{*/
106 #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
107 Rounding
= Flt_Rounds
;
110 switch(fegetround()) {
111 case FE_TOWARDZERO
: Rounding
= 0; break;
112 case FE_UPWARD
: Rounding
= 2; break;
113 case FE_DOWNWARD
: Rounding
= 3;
118 sign
= nz0
= nz
= decpt
= 0;
120 for(s
= s00
;;s
++) switch(*s
) {
142 #ifndef NO_HEX_FP /*{*/
144 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
151 #ifdef Honor_FLT_ROUNDS
153 fpi1
.rounding
= Rounding
;
157 switch((i
= gethex(&s
, &fpi1
, &exp
, &bb
, sign
)) & STRTOG_Retmask
) {
158 case STRTOG_NoNumber
:
165 copybits(bits
, fpi
.nbits
, bb
);
168 ULtod(((U
*)&rv
)->L
, bits
, exp
, i
);
181 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
188 if (c
== *decimalpoint
) {
189 for(i
= 1; decimalpoint
[i
]; ++i
)
190 if (s
[i
] != decimalpoint
[i
])
200 for(; c
== '0'; c
= *++s
)
202 if (c
> '0' && c
<= '9') {
210 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
215 for(i
= 1; i
< nz
; i
++)
218 else if (nd
<= DBL_DIG
+ 1)
222 else if (nd
<= DBL_DIG
+ 1)
230 if (c
== 'e' || c
== 'E') {
231 if (!nd
&& !nz
&& !nz0
) {
242 if (c
>= '0' && c
<= '9') {
245 if (c
> '0' && c
<= '9') {
248 while((c
= *++s
) >= '0' && c
<= '9')
250 if (s
- s1
> 8 || L
> 19999)
251 /* Avoid confusion from exponents
252 * so large that e might overflow.
254 e
= 19999; /* safe for 16 bit ints */
269 /* Check for Nan and Infinity */
271 static FPI fpinan
= /* only 52 explicit bits */
272 { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
277 if (match(&s
,"nf")) {
279 if (!match(&s
,"inity"))
281 word0(&rv
) = 0x7ff00000;
288 if (match(&s
, "an")) {
291 && hexnan(&s
, &fpinan
, bits
)
293 word0(&rv
) = 0x7ff00000 | bits
[1];
294 word1(&rv
) = bits
[0];
298 word0(&rv
) = NAN_WORD0
;
299 word1(&rv
) = NAN_WORD1
;
306 #endif /* INFNAN_CHECK */
315 /* Now we have nd0 digits, starting at s0, followed by a
316 * decimal point, followed by nd-nd0 digits. The number we're
317 * after is the integer represented by those digits times
322 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
327 oldinexact
= get_inexact();
329 dval(&rv
) = tens
[k
- 9] * dval(&rv
) + z
;
334 #ifndef Honor_FLT_ROUNDS
346 #ifdef Honor_FLT_ROUNDS
347 /* round correctly FLT_ROUNDS = 2 or 3 */
353 /* rv = */ rounded_product(dval(&rv
), tens
[e
]);
358 if (e
<= Ten_pmax
+ i
) {
359 /* A fancier test would sometimes let us do
360 * this for larger i values.
362 #ifdef Honor_FLT_ROUNDS
363 /* round correctly FLT_ROUNDS = 2 or 3 */
370 dval(&rv
) *= tens
[i
];
372 /* VAX exponent range is so narrow we must
373 * worry about overflow here...
376 word0(&rv
) -= P
*Exp_msk1
;
377 /* rv = */ rounded_product(dval(&rv
), tens
[e
]);
378 if ((word0(&rv
) & Exp_mask
)
379 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
381 word0(&rv
) += P
*Exp_msk1
;
383 /* rv = */ rounded_product(dval(&rv
), tens
[e
]);
388 #ifndef Inaccurate_Divide
389 else if (e
>= -Ten_pmax
) {
390 #ifdef Honor_FLT_ROUNDS
391 /* round correctly FLT_ROUNDS = 2 or 3 */
397 /* rv = */ rounded_quotient(dval(&rv
), tens
[-e
]);
408 oldinexact
= get_inexact();
410 #ifdef Avoid_Underflow
413 #ifdef Honor_FLT_ROUNDS
416 Rounding
= Rounding
== 2 ? 0 : 2;
422 #endif /*IEEE_Arith*/
424 /* Get starting approximation = rv * 10**e1 */
427 if ( (i
= e1
& 15) !=0)
428 dval(&rv
) *= tens
[i
];
430 if (e1
> DBL_MAX_10_EXP
) {
435 /* Can't trust HUGE_VAL */
437 #ifdef Honor_FLT_ROUNDS
439 case 0: /* toward 0 */
440 case 3: /* toward -infinity */
445 word0(&rv
) = Exp_mask
;
448 #else /*Honor_FLT_ROUNDS*/
449 word0(&rv
) = Exp_mask
;
451 #endif /*Honor_FLT_ROUNDS*/
453 /* set overflow bit */
455 dval(&rv0
) *= dval(&rv0
);
460 #endif /*IEEE_Arith*/
466 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
468 dval(&rv
) *= bigtens
[j
];
469 /* The last multiplication could overflow. */
470 word0(&rv
) -= P
*Exp_msk1
;
471 dval(&rv
) *= bigtens
[j
];
472 if ((z
= word0(&rv
) & Exp_mask
)
473 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
475 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
476 /* set to largest number */
477 /* (Can't trust DBL_MAX) */
482 word0(&rv
) += P
*Exp_msk1
;
487 if ( (i
= e1
& 15) !=0)
488 dval(&rv
) /= tens
[i
];
490 if (e1
>= 1 << n_bigtens
)
492 #ifdef Avoid_Underflow
495 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
497 dval(&rv
) *= tinytens
[j
];
498 if (scale
&& (j
= 2*P
+ 1 - ((word0(&rv
) & Exp_mask
)
499 >> Exp_shift
)) > 0) {
500 /* scaled rv is denormal; zap j low bits */
504 word0(&rv
) = (P
+2)*Exp_msk1
;
506 word0(&rv
) &= 0xffffffff << (j
-32);
509 word1(&rv
) &= 0xffffffff << j
;
512 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
514 dval(&rv
) *= tinytens
[j
];
515 /* The last multiplication could underflow. */
516 dval(&rv0
) = dval(&rv
);
517 dval(&rv
) *= tinytens
[j
];
519 dval(&rv
) = 2.*dval(&rv0
);
520 dval(&rv
) *= tinytens
[j
];
532 #ifndef Avoid_Underflow
535 /* The refinement below will clean
536 * this approximation up.
543 /* Now the hard part -- adjusting rv to the correct value.*/
545 /* Put digits into bd: true value = bd * 10^e */
547 bd0
= s2b(s0
, nd0
, nd
, y
, dplen
);
552 bb
= d2b(dval(&rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
568 #ifdef Honor_FLT_ROUNDS
572 #ifdef Avoid_Underflow
574 i
= j
+ bbbits
- 1; /* logb(&rv) */
575 if (i
< Emin
) /* denormal */
579 #else /*Avoid_Underflow*/
580 #ifdef Sudden_Underflow
582 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
586 #else /*Sudden_Underflow*/
588 i
= j
+ bbbits
- 1; /* logb(&rv) */
589 if (i
< Emin
) /* denormal */
593 #endif /*Sudden_Underflow*/
594 #endif /*Avoid_Underflow*/
597 #ifdef Avoid_Underflow
600 i
= bb2
< bd2
? bb2
: bd2
;
609 bs
= pow5mult(bs
, bb5
);
615 bb
= lshift(bb
, bb2
);
617 bd
= pow5mult(bd
, bd5
);
619 bd
= lshift(bd
, bd2
);
621 bs
= lshift(bs
, bs2
);
622 delta
= diff(bb
, bd
);
626 #ifdef Honor_FLT_ROUNDS
629 /* Error is less than an ulp */
630 if (!delta
->x
[0] && delta
->wds
<= 1) {
646 && !(word0(&rv
) & Frac_mask
)) {
647 y
= word0(&rv
) & Exp_mask
;
648 #ifdef Avoid_Underflow
649 if (!scale
|| y
> 2*P
*Exp_msk1
)
654 delta
= lshift(delta
,Log2P
);
655 if (cmp(delta
, bs
) <= 0)
660 #ifdef Avoid_Underflow
661 if (scale
&& (y
= word0(&rv
) & Exp_mask
)
663 word0(&adj
) += (2*P
+1)*Exp_msk1
- y
;
665 #ifdef Sudden_Underflow
666 if ((word0(&rv
) & Exp_mask
) <=
668 word0(&rv
) += P
*Exp_msk1
;
669 dval(&rv
) += adj
*ulp(&rv
);
670 word0(&rv
) -= P
*Exp_msk1
;
673 #endif /*Sudden_Underflow*/
674 #endif /*Avoid_Underflow*/
675 dval(&rv
) += adj
*ulp(&rv
);
679 dval(&adj
) = ratio(delta
, bs
);
682 if (adj
<= 0x7ffffffe) {
683 /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */
686 if (!((Rounding
>>1) ^ dsign
))
691 #ifdef Avoid_Underflow
692 if (scale
&& (y
= word0(&rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
693 word0(&adj
) += (2*P
+1)*Exp_msk1
- y
;
695 #ifdef Sudden_Underflow
696 if ((word0(&rv
) & Exp_mask
) <= P
*Exp_msk1
) {
697 word0(&rv
) += P
*Exp_msk1
;
698 dval(&adj
) *= ulp(&rv
);
703 word0(&rv
) -= P
*Exp_msk1
;
706 #endif /*Sudden_Underflow*/
707 #endif /*Avoid_Underflow*/
708 dval(&adj
) *= ulp(&rv
);
710 if (word0(&rv
) == Big0
&& word1(&rv
) == Big1
)
718 #endif /*Honor_FLT_ROUNDS*/
721 /* Error is less than half an ulp -- check for
722 * special case of mantissa a power of two.
724 if (dsign
|| word1(&rv
) || word0(&rv
) & Bndry_mask
726 #ifdef Avoid_Underflow
727 || (word0(&rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
729 || (word0(&rv
) & Exp_mask
) <= Exp_msk1
734 if (!delta
->x
[0] && delta
->wds
<= 1)
739 if (!delta
->x
[0] && delta
->wds
<= 1) {
746 delta
= lshift(delta
,Log2P
);
747 if (cmp(delta
, bs
) > 0)
752 /* exactly half-way between */
754 if ((word0(&rv
) & Bndry_mask1
) == Bndry_mask1
756 #ifdef Avoid_Underflow
757 (scale
&& (y
= word0(&rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
758 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
761 /*boundary case -- increment exponent*/
762 word0(&rv
) = (word0(&rv
) & Exp_mask
)
769 #ifdef Avoid_Underflow
775 else if (!(word0(&rv
) & Bndry_mask
) && !word1(&rv
)) {
777 /* boundary case -- decrement exponent */
778 #ifdef Sudden_Underflow /*{{*/
779 L
= word0(&rv
) & Exp_mask
;
783 #ifdef Avoid_Underflow
784 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
787 #endif /*Avoid_Underflow*/
791 #else /*Sudden_Underflow}{*/
792 #ifdef Avoid_Underflow
794 L
= word0(&rv
) & Exp_mask
;
795 if (L
<= (2*P
+1)*Exp_msk1
) {
796 if (L
> (P
+2)*Exp_msk1
)
800 /* rv = smallest denormal */
804 #endif /*Avoid_Underflow*/
805 L
= (word0(&rv
) & Exp_mask
) - Exp_msk1
;
806 #endif /*Sudden_Underflow}}*/
807 word0(&rv
) = L
| Bndry_mask1
;
808 word1(&rv
) = 0xffffffff;
816 if (!(word1(&rv
) & LSB
))
820 dval(&rv
) += ulp(&rv
);
823 dval(&rv
) -= ulp(&rv
);
824 #ifndef Sudden_Underflow
829 #ifdef Avoid_Underflow
835 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
837 aadj
= dval(&aadj1
) = 1.;
838 else if (word1(&rv
) || word0(&rv
) & Bndry_mask
) {
839 #ifndef Sudden_Underflow
840 if (word1(&rv
) == Tiny1
&& !word0(&rv
))
847 /* special case -- power of FLT_RADIX to be */
848 /* rounded down... */
850 if (aadj
< 2./FLT_RADIX
)
854 dval(&aadj1
) = -aadj
;
859 dval(&aadj1
) = dsign
? aadj
: -aadj
;
860 #ifdef Check_FLT_ROUNDS
862 case 2: /* towards +infinity */
865 case 0: /* towards 0 */
866 case 3: /* towards -infinity */
872 #endif /*Check_FLT_ROUNDS*/
874 y
= word0(&rv
) & Exp_mask
;
876 /* Check for overflow */
878 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
879 dval(&rv0
) = dval(&rv
);
880 word0(&rv
) -= P
*Exp_msk1
;
881 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
882 dval(&rv
) += dval(&adj
);
883 if ((word0(&rv
) & Exp_mask
) >=
884 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
885 if (word0(&rv0
) == Big0
&& word1(&rv0
) == Big1
)
892 word0(&rv
) += P
*Exp_msk1
;
895 #ifdef Avoid_Underflow
896 if (scale
&& y
<= 2*P
*Exp_msk1
) {
897 if (aadj
<= 0x7fffffff) {
901 dval(&aadj1
) = dsign
? aadj
: -aadj
;
903 word0(&aadj1
) += (2*P
+1)*Exp_msk1
- y
;
905 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
906 dval(&rv
) += dval(&adj
);
908 #ifdef Sudden_Underflow
909 if ((word0(&rv
) & Exp_mask
) <= P
*Exp_msk1
) {
910 dval(&rv0
) = dval(&rv
);
911 word0(&rv
) += P
*Exp_msk1
;
912 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
915 if ((word0(&rv
) & Exp_mask
) < P
*Exp_msk1
)
917 if ((word0(&rv
) & Exp_mask
) <= P
*Exp_msk1
)
920 if (word0(&rv0
) == Tiny0
921 && word1(&rv0
) == Tiny1
)
928 word0(&rv
) -= P
*Exp_msk1
;
931 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
934 #else /*Sudden_Underflow*/
935 /* Compute dval(&adj) so that the IEEE rounding rules will
936 * correctly round rv + dval(&adj) in some half-way cases.
937 * If rv * ulp(&rv) is denormalized (i.e.,
938 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
939 * trouble from bits lost to denormalization;
940 * example: 1.2e-307 .
942 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
943 dval(&aadj1
) = (double)(int)(aadj
+ 0.5);
945 dval(&aadj1
) = -dval(&aadj1
);
947 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
949 #endif /*Sudden_Underflow*/
950 #endif /*Avoid_Underflow*/
952 z
= word0(&rv
) & Exp_mask
;
954 #ifdef Avoid_Underflow
958 /* Can we stop now? */
961 /* The tolerances below are conservative. */
962 if (dsign
|| word1(&rv
) || word0(&rv
) & Bndry_mask
) {
963 if (aadj
< .4999999 || aadj
> .5000001)
966 else if (aadj
< .4999999/FLT_RADIX
)
979 word0(&rv0
) = Exp_1
+ (70 << Exp_shift
);
984 else if (!oldinexact
)
987 #ifdef Avoid_Underflow
989 word0(&rv0
) = Exp_1
- 2*P
*Exp_msk1
;
991 dval(&rv
) *= dval(&rv0
);
993 /* try to avoid the bug of testing an 8087 register value */
995 if (!(word0(&rv
) & Exp_mask
))
997 if (word0(&rv
) == 0 && word1(&rv
) == 0)
1002 #endif /* Avoid_Underflow */
1004 if (inexact
&& !(word0(&rv
) & Exp_mask
)) {
1005 /* set underflow bit */
1006 dval(&rv0
) = 1e-300;
1007 dval(&rv0
) *= dval(&rv0
);
1019 return sign
? -dval(&rv
) : dval(&rv
);