]>
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 "."). */
32 #include "xlocale_private.h"
45 #define Avoid_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. */
49 static CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128,
50 9007199254740992.*9007199254740992.e
-256
55 #ifdef Honor_FLT_ROUNDS
56 #undef Check_FLT_ROUNDS
57 #define Check_FLT_ROUNDS
59 #define Rounding Flt_Rounds
65 (s00
, se
, loc
) CONST
char *s00
; char **se
; locale_t loc
;
67 (CONST
char *s00
, char **se
, locale_t loc
)
70 #ifdef Avoid_Underflow
73 int bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, dsign
,
74 e
, e1
, esign
, i
, j
, k
, nd
, nd0
, nf
, nz
, nz0
, sign
;
75 CONST
char *s
, *s0
, *s1
;
79 U adj
, aadj1
, rv
, rv0
;
81 Bigint
*bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
;
83 int inexact
, oldinexact
;
85 #ifdef USE_LOCALE /*{{*/
86 NORMALIZE_LOCALE(loc
);
87 #ifdef NO_LOCALE_CACHE
88 char *decimalpoint
= localeconv_l(loc
)->decimal_point
;
89 int dplen
= strlen(decimalpoint
);
92 static char *decimalpoint_cache
;
94 if (!(s0
= decimalpoint_cache
)) {
95 s0
= localeconv_l(loc
)->decimal_point
;
96 if ((decimalpoint_cache
= (char*)MALLOC(strlen(s0
) + 1))) {
97 strcpy(decimalpoint_cache
, s0
);
98 s0
= decimalpoint_cache
;
102 decimalpoint
= (char*)s0
;
103 #endif /*NO_LOCALE_CACHE*/
104 #else /*USE_LOCALE}{*/
106 #endif /*USE_LOCALE}}*/
108 #ifdef Honor_FLT_ROUNDS /*{*/
110 #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
111 Rounding
= Flt_Rounds
;
114 switch(fegetround()) {
115 case FE_TOWARDZERO
: Rounding
= 0; break;
116 case FE_UPWARD
: Rounding
= 2; break;
117 case FE_DOWNWARD
: Rounding
= 3;
122 sign
= nz0
= nz
= decpt
= 0;
124 for(s
= s00
;;s
++) switch(*s
) {
146 #ifndef NO_HEX_FP /*{*/
148 static CONST FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
155 #ifdef Honor_FLT_ROUNDS
157 fpi1
.rounding
= Rounding
;
161 switch((i
= gethex(&s
, &fpi1
, &exp
, &bb
, sign
, loc
)) & STRTOG_Retmask
) {
162 case STRTOG_NoNumber
:
169 copybits(bits
, fpi
.nbits
, bb
);
172 ULtod(((U
*)&rv
)->L
, bits
, exp
, i
);
185 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
192 if (c
== *decimalpoint
) {
193 for(i
= 1; decimalpoint
[i
]; ++i
)
194 if (s
[i
] != decimalpoint
[i
])
204 for(; c
== '0'; c
= *++s
)
206 if (c
> '0' && c
<= '9') {
214 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
219 for(i
= 1; i
< nz
; i
++)
222 else if (nd
<= DBL_DIG
+ 1)
226 else if (nd
<= DBL_DIG
+ 1)
234 if (c
== 'e' || c
== 'E') {
235 if (!nd
&& !nz
&& !nz0
) {
246 if (c
>= '0' && c
<= '9') {
249 if (c
> '0' && c
<= '9') {
252 while((c
= *++s
) >= '0' && c
<= '9')
254 if (s
- s1
> 8 || L
> 19999)
255 /* Avoid confusion from exponents
256 * so large that e might overflow.
258 e
= 19999; /* safe for 16 bit ints */
273 /* Check for Nan and Infinity */
275 static CONST FPI fpinan
= /* only 52 explicit bits */
276 { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
281 if (match(&s
,"nf")) {
283 if (!match(&s
,"inity"))
285 word0(&rv
) = 0x7ff00000;
292 if (match(&s
, "an")) {
295 && hexnan(&s
, &fpinan
, bits
)
297 word0(&rv
) = 0x7ff00000 | bits
[1];
298 word1(&rv
) = bits
[0];
302 word0(&rv
) = NAN_WORD0
;
303 word1(&rv
) = NAN_WORD1
;
310 #endif /* INFNAN_CHECK */
317 #define FPIEMIN (1-1023-53+1) // fpi.emin
318 #define FPINBITS 52 // fpi.nbits
319 TRUNCATE_DIGITS(s0
, strunc
, nd
, nd0
, nf
, FPINBITS
, FPIEMIN
, dplen
);
322 /* Now we have nd0 digits, starting at s0, followed by a
323 * decimal point, followed by nd-nd0 digits. The number we're
324 * after is the integer represented by those digits times
329 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
334 oldinexact
= get_inexact();
336 dval(&rv
) = tens
[k
- 9] * dval(&rv
) + z
;
341 #ifndef Honor_FLT_ROUNDS
353 #ifdef Honor_FLT_ROUNDS
354 /* round correctly FLT_ROUNDS = 2 or 3 */
356 dval(&rv
) = -dval(&rv
);
360 /* rv = */ rounded_product(dval(&rv
), tens
[e
]);
365 if (e
<= Ten_pmax
+ i
) {
366 /* A fancier test would sometimes let us do
367 * this for larger i values.
369 #ifdef Honor_FLT_ROUNDS
370 /* round correctly FLT_ROUNDS = 2 or 3 */
372 dval(&rv
) = -dval(&rv
);
377 dval(&rv
) *= tens
[i
];
379 /* VAX exponent range is so narrow we must
380 * worry about overflow here...
383 word0(&rv
) -= P
*Exp_msk1
;
384 /* rv = */ rounded_product(dval(&rv
), tens
[e
]);
385 if ((word0(&rv
) & Exp_mask
)
386 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
388 word0(&rv
) += P
*Exp_msk1
;
390 /* rv = */ rounded_product(dval(&rv
), tens
[e
]);
395 #ifndef Inaccurate_Divide
396 else if (e
>= -Ten_pmax
) {
397 #ifdef Honor_FLT_ROUNDS
398 /* round correctly FLT_ROUNDS = 2 or 3 */
400 dval(&rv
) = -dval(&rv
);
404 /* rv = */ rounded_quotient(dval(&rv
), tens
[-e
]);
415 oldinexact
= get_inexact();
417 #ifdef Avoid_Underflow
420 #ifdef Honor_FLT_ROUNDS
423 Rounding
= Rounding
== 2 ? 0 : 2;
429 #endif /*IEEE_Arith*/
431 /* Get starting approximation = rv * 10**e1 */
434 if ( (i
= e1
& 15) !=0)
435 dval(&rv
) *= tens
[i
];
437 if (e1
> DBL_MAX_10_EXP
) {
442 /* Can't trust HUGE_VAL */
444 #ifdef Honor_FLT_ROUNDS
446 case 0: /* toward 0 */
447 case 3: /* toward -infinity */
452 word0(&rv
) = Exp_mask
;
455 #else /*Honor_FLT_ROUNDS*/
456 word0(&rv
) = Exp_mask
;
458 #endif /*Honor_FLT_ROUNDS*/
460 /* set overflow bit */
462 dval(&rv0
) *= dval(&rv0
);
467 #endif /*IEEE_Arith*/
473 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
475 dval(&rv
) *= bigtens
[j
];
476 /* The last multiplication could overflow. */
477 word0(&rv
) -= P
*Exp_msk1
;
478 dval(&rv
) *= bigtens
[j
];
479 if ((z
= word0(&rv
) & Exp_mask
)
480 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
482 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
483 /* set to largest number */
484 /* (Can't trust DBL_MAX) */
489 word0(&rv
) += P
*Exp_msk1
;
494 if ( (i
= e1
& 15) !=0)
495 dval(&rv
) /= tens
[i
];
497 if (e1
>= 1 << n_bigtens
)
499 #ifdef Avoid_Underflow
502 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
504 dval(&rv
) *= tinytens
[j
];
505 if (scale
&& (j
= 2*P
+ 1 - ((word0(&rv
) & Exp_mask
)
506 >> Exp_shift
)) > 0) {
507 /* scaled rv is denormal; zap j low bits */
511 word0(&rv
) = (P
+2)*Exp_msk1
;
513 word0(&rv
) &= 0xffffffff << (j
-32);
516 word1(&rv
) &= 0xffffffff << j
;
519 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
521 dval(&rv
) *= tinytens
[j
];
522 /* The last multiplication could underflow. */
523 dval(&rv0
) = dval(&rv
);
524 dval(&rv
) *= tinytens
[j
];
526 dval(&rv
) = 2.*dval(&rv0
);
527 dval(&rv
) *= tinytens
[j
];
539 #ifndef Avoid_Underflow
542 /* The refinement below will clean
543 * this approximation up.
550 /* Now the hard part -- adjusting rv to the correct value.*/
552 /* Put digits into bd: true value = bd * 10^e */
554 bd0
= s2b(s0
, nd0
, nd
, y
, dplen
);
559 bb
= d2b(dval(&rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
575 #ifdef Honor_FLT_ROUNDS
579 #ifdef Avoid_Underflow
581 i
= j
+ bbbits
- 1; /* logb(&rv) */
582 if (i
< Emin
) /* denormal */
586 #else /*Avoid_Underflow*/
587 #ifdef Sudden_Underflow
589 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
593 #else /*Sudden_Underflow*/
595 i
= j
+ bbbits
- 1; /* logb(&rv) */
596 if (i
< Emin
) /* denormal */
600 #endif /*Sudden_Underflow*/
601 #endif /*Avoid_Underflow*/
604 #ifdef Avoid_Underflow
607 i
= bb2
< bd2
? bb2
: bd2
;
616 bs
= pow5mult(bs
, bb5
);
622 bb
= lshift(bb
, bb2
);
624 bd
= pow5mult(bd
, bd5
);
626 bd
= lshift(bd
, bd2
);
628 bs
= lshift(bs
, bs2
);
629 delta
= diff(bb
, bd
);
633 #ifdef Honor_FLT_ROUNDS
636 /* Error is less than an ulp */
637 if (!delta
->x
[0] && delta
->wds
<= 1) {
653 && !(word0(&rv
) & Frac_mask
)) {
654 y
= word0(&rv
) & Exp_mask
;
655 #ifdef Avoid_Underflow
656 if (!scale
|| y
> 2*P
*Exp_msk1
)
661 delta
= lshift(delta
,Log2P
);
662 if (cmp(delta
, bs
) <= 0)
667 #ifdef Avoid_Underflow
668 if (scale
&& (y
= word0(&rv
) & Exp_mask
)
670 word0(&adj
) += (2*P
+1)*Exp_msk1
- y
;
672 #ifdef Sudden_Underflow
673 if ((word0(&rv
) & Exp_mask
) <=
675 word0(&rv
) += P
*Exp_msk1
;
676 dval(&rv
) += adj
*ulp(&rv
);
677 word0(&rv
) -= P
*Exp_msk1
;
680 #endif /*Sudden_Underflow*/
681 #endif /*Avoid_Underflow*/
682 dval(&rv
) += dval(&adj
)*ulp(&rv
);
686 dval(&adj
) = ratio(delta
, bs
);
689 if (dval(&adj
) <= 0x7ffffffe) {
690 /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */
692 if (y
!= dval(&adj
)) {
693 if (!((Rounding
>>1) ^ dsign
))
698 #ifdef Avoid_Underflow
699 if (scale
&& (y
= word0(&rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
700 word0(&adj
) += (2*P
+1)*Exp_msk1
- y
;
702 #ifdef Sudden_Underflow
703 if ((word0(&rv
) & Exp_mask
) <= P
*Exp_msk1
) {
704 word0(&rv
) += P
*Exp_msk1
;
705 dval(&adj
) *= ulp(&rv
);
710 word0(&rv
) -= P
*Exp_msk1
;
713 #endif /*Sudden_Underflow*/
714 #endif /*Avoid_Underflow*/
715 dval(&adj
) *= ulp(&rv
);
717 if (word0(&rv
) == Big0
&& word1(&rv
) == Big1
)
719 dval(&rv
) += dval(&adj
);
722 dval(&rv
) -= dval(&adj
);
725 #endif /*Honor_FLT_ROUNDS*/
728 /* Error is less than half an ulp -- check for
729 * special case of mantissa a power of two.
731 if (dsign
|| word1(&rv
) || word0(&rv
) & Bndry_mask
733 #ifdef Avoid_Underflow
734 || (word0(&rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
736 || (word0(&rv
) & Exp_mask
) <= Exp_msk1
741 if (!delta
->x
[0] && delta
->wds
<= 1)
746 if (!delta
->x
[0] && delta
->wds
<= 1) {
753 delta
= lshift(delta
,Log2P
);
754 if (cmp(delta
, bs
) > 0)
759 /* exactly half-way between */
761 if ((word0(&rv
) & Bndry_mask1
) == Bndry_mask1
763 #ifdef Avoid_Underflow
764 (scale
&& (y
= word0(&rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
765 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
768 /*boundary case -- increment exponent*/
769 word0(&rv
) = (word0(&rv
) & Exp_mask
)
776 #ifdef Avoid_Underflow
782 else if (!(word0(&rv
) & Bndry_mask
) && !word1(&rv
)) {
784 /* boundary case -- decrement exponent */
785 #ifdef Sudden_Underflow /*{{*/
786 L
= word0(&rv
) & Exp_mask
;
790 #ifdef Avoid_Underflow
791 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
794 #endif /*Avoid_Underflow*/
798 #else /*Sudden_Underflow}{*/
799 #ifdef Avoid_Underflow
801 L
= word0(&rv
) & Exp_mask
;
802 if (L
<= (2*P
+1)*Exp_msk1
) {
803 if (L
> (P
+2)*Exp_msk1
)
807 /* rv = smallest denormal */
811 #endif /*Avoid_Underflow*/
812 L
= (word0(&rv
) & Exp_mask
) - Exp_msk1
;
813 #endif /*Sudden_Underflow}}*/
814 word0(&rv
) = L
| Bndry_mask1
;
815 word1(&rv
) = 0xffffffff;
823 if (!(word1(&rv
) & LSB
))
827 dval(&rv
) += ulp(&rv
);
830 dval(&rv
) -= ulp(&rv
);
831 #ifndef Sudden_Underflow
836 #ifdef Avoid_Underflow
842 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
844 aadj
= dval(&aadj1
) = 1.;
845 else if (word1(&rv
) || word0(&rv
) & Bndry_mask
) {
846 #ifndef Sudden_Underflow
847 if (word1(&rv
) == Tiny1
&& !word0(&rv
))
854 /* special case -- power of FLT_RADIX to be */
855 /* rounded down... */
857 if (aadj
< 2./FLT_RADIX
)
861 dval(&aadj1
) = -aadj
;
866 dval(&aadj1
) = dsign
? aadj
: -aadj
;
867 #ifdef Check_FLT_ROUNDS
869 case 2: /* towards +infinity */
872 case 0: /* towards 0 */
873 case 3: /* towards -infinity */
879 #endif /*Check_FLT_ROUNDS*/
881 y
= word0(&rv
) & Exp_mask
;
883 /* Check for overflow */
885 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
886 dval(&rv0
) = dval(&rv
);
887 word0(&rv
) -= P
*Exp_msk1
;
888 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
889 dval(&rv
) += dval(&adj
);
890 if ((word0(&rv
) & Exp_mask
) >=
891 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
892 if (word0(&rv0
) == Big0
&& word1(&rv0
) == Big1
)
899 word0(&rv
) += P
*Exp_msk1
;
902 #ifdef Avoid_Underflow
903 if (scale
&& y
<= 2*P
*Exp_msk1
) {
904 if (aadj
<= 0x7fffffff) {
908 dval(&aadj1
) = dsign
? aadj
: -aadj
;
910 word0(&aadj1
) += (2*P
+1)*Exp_msk1
- y
;
912 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
913 dval(&rv
) += dval(&adj
);
915 #ifdef Sudden_Underflow
916 if ((word0(&rv
) & Exp_mask
) <= P
*Exp_msk1
) {
917 dval(&rv0
) = dval(&rv
);
918 word0(&rv
) += P
*Exp_msk1
;
919 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
922 if ((word0(&rv
) & Exp_mask
) < P
*Exp_msk1
)
924 if ((word0(&rv
) & Exp_mask
) <= P
*Exp_msk1
)
927 if (word0(&rv0
) == Tiny0
928 && word1(&rv0
) == Tiny1
)
935 word0(&rv
) -= P
*Exp_msk1
;
938 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
941 #else /*Sudden_Underflow*/
942 /* Compute dval(&adj) so that the IEEE rounding rules will
943 * correctly round rv + dval(&adj) in some half-way cases.
944 * If rv * ulp(&rv) is denormalized (i.e.,
945 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
946 * trouble from bits lost to denormalization;
947 * example: 1.2e-307 .
949 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
950 dval(&aadj1
) = (double)(int)(aadj
+ 0.5);
952 dval(&aadj1
) = -dval(&aadj1
);
954 dval(&adj
) = dval(&aadj1
) * ulp(&rv
);
956 #endif /*Sudden_Underflow*/
957 #endif /*Avoid_Underflow*/
959 z
= word0(&rv
) & Exp_mask
;
961 #ifdef Avoid_Underflow
965 /* Can we stop now? */
968 /* The tolerances below are conservative. */
969 if (dsign
|| word1(&rv
) || word0(&rv
) & Bndry_mask
) {
970 if (aadj
< .4999999 || aadj
> .5000001)
973 else if (aadj
< .4999999/FLT_RADIX
)
986 word0(&rv0
) = Exp_1
+ (70 << Exp_shift
);
991 else if (!oldinexact
)
994 #ifdef Avoid_Underflow
996 word0(&rv0
) = Exp_1
- 2*P
*Exp_msk1
;
998 dval(&rv
) *= dval(&rv0
);
1000 /* try to avoid the bug of testing an 8087 register value */
1001 #if defined(IEEE_Arith) && __DARWIN_UNIX03
1002 if (!(word0(&rv
) & Exp_mask
))
1004 if (word0(&rv
) == 0 && word1(&rv
) == 0)
1009 #endif /* Avoid_Underflow */
1011 if (inexact
&& !(word0(&rv
) & Exp_mask
)) {
1012 /* set underflow bit */
1013 dval(&rv0
) = 1e-300;
1014 dval(&rv0
) *= dval(&rv0
);
1032 return sign
? -dval(&rv
) : dval(&rv
);
1038 (s00
, se
) CONST
char *s00
; char **se
;
1040 (CONST
char *s00
, char **se
)
1043 return strtod_l(s00
, se
, __current_locale());