]>
git.saurik.com Git - apple/libc.git/blob - gdtoa/gdtoa-strtod-fbsd.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
;
76 double aadj
, aadj1
, adj
, rv
, rv0
;
79 Bigint
*bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
;
81 int inexact
, oldinexact
;
84 NORMALIZE_LOCALE(loc
);
85 #ifdef NO_LOCALE_CACHE
86 char *decimalpoint
= localeconv_l(loc
)->decimal_point
;
89 static char *decimalpoint_cache
;
90 if (!(s0
= decimalpoint_cache
)) {
91 s0
= localeconv_l(loc
)->decimal_point
;
92 if ((decimalpoint_cache
= (char*)malloc(strlen(s0
) + 1))) {
93 strcpy(decimalpoint_cache
, s0
);
94 s0
= decimalpoint_cache
;
97 decimalpoint
= (char*)s0
;
100 #ifdef Honor_FLT_ROUNDS /*{*/
102 #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
103 Rounding
= Flt_Rounds
;
106 switch(fegetround()) {
107 case FE_TOWARDZERO
: Rounding
= 0; break;
108 case FE_UPWARD
: Rounding
= 2; break;
109 case FE_DOWNWARD
: Rounding
= 3;
114 sign
= nz0
= nz
= decpt
= 0;
116 for(s
= s00
;;s
++) switch(*s
) {
138 #ifndef NO_HEX_FP /*{*/
140 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
147 #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) /*{{*/
149 #ifdef Honor_FLT_ROUNDS /*{{*/
150 fpi1
.rounding
= Rounding
;
152 switch(fegetround()) {
153 case FE_TOWARDZERO
: fpi1
.rounding
= 0; break;
154 case FE_UPWARD
: fpi1
.rounding
= 2; break;
155 case FE_DOWNWARD
: fpi1
.rounding
= 3;
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 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];
302 word0(rv
) = NAN_WORD0
;
303 word1(rv
) = NAN_WORD1
;
310 #endif /* INFNAN_CHECK */
319 /* Now we have nd0 digits, starting at s0, followed by a
320 * decimal point, followed by nd-nd0 digits. The number we're
321 * after is the integer represented by those digits times
326 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
331 oldinexact
= get_inexact();
333 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
338 #ifndef Honor_FLT_ROUNDS
350 #ifdef Honor_FLT_ROUNDS
351 /* round correctly FLT_ROUNDS = 2 or 3 */
357 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
362 if (e
<= Ten_pmax
+ i
) {
363 /* A fancier test would sometimes let us do
364 * this for larger i values.
366 #ifdef Honor_FLT_ROUNDS
367 /* round correctly FLT_ROUNDS = 2 or 3 */
376 /* VAX exponent range is so narrow we must
377 * worry about overflow here...
380 word0(rv
) -= P
*Exp_msk1
;
381 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
382 if ((word0(rv
) & Exp_mask
)
383 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
385 word0(rv
) += P
*Exp_msk1
;
387 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
392 #ifndef Inaccurate_Divide
393 else if (e
>= -Ten_pmax
) {
394 #ifdef Honor_FLT_ROUNDS
395 /* round correctly FLT_ROUNDS = 2 or 3 */
401 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
412 oldinexact
= get_inexact();
414 #ifdef Avoid_Underflow
417 #ifdef Honor_FLT_ROUNDS
420 Rounding
= Rounding
== 2 ? 0 : 2;
426 #endif /*IEEE_Arith*/
428 /* Get starting approximation = rv * 10**e1 */
431 if ( (i
= e1
& 15) !=0)
434 if (e1
> DBL_MAX_10_EXP
) {
439 /* Can't trust HUGE_VAL */
441 #ifdef Honor_FLT_ROUNDS
443 case 0: /* toward 0 */
444 case 3: /* toward -infinity */
449 word0(rv
) = Exp_mask
;
452 #else /*Honor_FLT_ROUNDS*/
453 word0(rv
) = Exp_mask
;
455 #endif /*Honor_FLT_ROUNDS*/
457 /* set overflow bit */
459 dval(rv0
) *= dval(rv0
);
464 #endif /*IEEE_Arith*/
470 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
472 dval(rv
) *= bigtens
[j
];
473 /* The last multiplication could overflow. */
474 word0(rv
) -= P
*Exp_msk1
;
475 dval(rv
) *= bigtens
[j
];
476 if ((z
= word0(rv
) & Exp_mask
)
477 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
479 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
480 /* set to largest number */
481 /* (Can't trust DBL_MAX) */
486 word0(rv
) += P
*Exp_msk1
;
491 if ( (i
= e1
& 15) !=0)
494 if (e1
>= 1 << n_bigtens
)
496 #ifdef Avoid_Underflow
499 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
501 dval(rv
) *= tinytens
[j
];
502 if (scale
&& (j
= 2*P
+ 1 - ((word0(rv
) & Exp_mask
)
503 >> Exp_shift
)) > 0) {
504 /* scaled rv is denormal; zap j low bits */
508 word0(rv
) = (P
+2)*Exp_msk1
;
510 word0(rv
) &= 0xffffffff << j
-32;
513 word1(rv
) &= 0xffffffff << j
;
516 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
518 dval(rv
) *= tinytens
[j
];
519 /* The last multiplication could underflow. */
520 dval(rv0
) = dval(rv
);
521 dval(rv
) *= tinytens
[j
];
523 dval(rv
) = 2.*dval(rv0
);
524 dval(rv
) *= tinytens
[j
];
536 #ifndef Avoid_Underflow
539 /* The refinement below will clean
540 * this approximation up.
547 /* Now the hard part -- adjusting rv to the correct value.*/
549 /* Put digits into bd: true value = bd * 10^e */
552 bd0
= s2b(s0
, nd0
, nd
, y
, strlen(decimalpoint
));
554 bd0
= s2b(s0
, nd0
, nd
, y
, 1);
560 bb
= d2b(dval(rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
576 #ifdef Honor_FLT_ROUNDS
580 #ifdef Avoid_Underflow
582 i
= j
+ bbbits
- 1; /* logb(rv) */
583 if (i
< Emin
) /* denormal */
587 #else /*Avoid_Underflow*/
588 #ifdef Sudden_Underflow
590 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
594 #else /*Sudden_Underflow*/
596 i
= j
+ bbbits
- 1; /* logb(rv) */
597 if (i
< Emin
) /* denormal */
601 #endif /*Sudden_Underflow*/
602 #endif /*Avoid_Underflow*/
605 #ifdef Avoid_Underflow
608 i
= bb2
< bd2
? bb2
: bd2
;
617 bs
= pow5mult(bs
, bb5
);
623 bb
= lshift(bb
, bb2
);
625 bd
= pow5mult(bd
, bd5
);
627 bd
= lshift(bd
, bd2
);
629 bs
= lshift(bs
, bs2
);
630 delta
= diff(bb
, bd
);
634 #ifdef Honor_FLT_ROUNDS
637 /* Error is less than an ulp */
638 if (!delta
->x
[0] && delta
->wds
<= 1) {
654 && !(word0(rv
) & Frac_mask
)) {
655 y
= word0(rv
) & Exp_mask
;
656 #ifdef Avoid_Underflow
657 if (!scale
|| y
> 2*P
*Exp_msk1
)
662 delta
= lshift(delta
,Log2P
);
663 if (cmp(delta
, bs
) <= 0)
668 #ifdef Avoid_Underflow
669 if (scale
&& (y
= word0(rv
) & Exp_mask
)
671 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
673 #ifdef Sudden_Underflow
674 if ((word0(rv
) & Exp_mask
) <=
676 word0(rv
) += P
*Exp_msk1
;
677 dval(rv
) += adj
*ulp(dval(rv
));
678 word0(rv
) -= P
*Exp_msk1
;
681 #endif /*Sudden_Underflow*/
682 #endif /*Avoid_Underflow*/
683 dval(rv
) += adj
*ulp(dval(rv
));
687 adj
= ratio(delta
, bs
);
690 if (adj
<= 0x7ffffffe) {
691 /* adj = Rounding ? ceil(adj) : floor(adj); */
694 if (!((Rounding
>>1) ^ dsign
))
699 #ifdef Avoid_Underflow
700 if (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
701 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
703 #ifdef Sudden_Underflow
704 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
705 word0(rv
) += P
*Exp_msk1
;
706 adj
*= ulp(dval(rv
));
711 word0(rv
) -= P
*Exp_msk1
;
714 #endif /*Sudden_Underflow*/
715 #endif /*Avoid_Underflow*/
716 adj
*= ulp(dval(rv
));
718 if (word0(rv
) == Big0
&& word1(rv
) == Big1
)
726 #endif /*Honor_FLT_ROUNDS*/
729 /* Error is less than half an ulp -- check for
730 * special case of mantissa a power of two.
732 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
734 #ifdef Avoid_Underflow
735 || (word0(rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
737 || (word0(rv
) & Exp_mask
) <= Exp_msk1
742 if (!delta
->x
[0] && delta
->wds
<= 1)
747 if (!delta
->x
[0] && delta
->wds
<= 1) {
754 delta
= lshift(delta
,Log2P
);
755 if (cmp(delta
, bs
) > 0)
760 /* exactly half-way between */
762 if ((word0(rv
) & Bndry_mask1
) == Bndry_mask1
764 #ifdef Avoid_Underflow
765 (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
766 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
769 /*boundary case -- increment exponent*/
770 word0(rv
) = (word0(rv
) & Exp_mask
)
777 #ifdef Avoid_Underflow
783 else if (!(word0(rv
) & Bndry_mask
) && !word1(rv
)) {
785 /* boundary case -- decrement exponent */
786 #ifdef Sudden_Underflow /*{{*/
787 L
= word0(rv
) & Exp_mask
;
791 #ifdef Avoid_Underflow
792 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
795 #endif /*Avoid_Underflow*/
799 #else /*Sudden_Underflow}{*/
800 #ifdef Avoid_Underflow
802 L
= word0(rv
) & Exp_mask
;
803 if (L
<= (2*P
+1)*Exp_msk1
) {
804 if (L
> (P
+2)*Exp_msk1
)
808 /* rv = smallest denormal */
812 #endif /*Avoid_Underflow*/
813 L
= (word0(rv
) & Exp_mask
) - Exp_msk1
;
814 #endif /*Sudden_Underflow}}*/
815 word0(rv
) = L
| Bndry_mask1
;
816 word1(rv
) = 0xffffffff;
824 if (!(word1(rv
) & LSB
))
828 dval(rv
) += ulp(dval(rv
));
831 dval(rv
) -= ulp(dval(rv
));
832 #ifndef Sudden_Underflow
837 #ifdef Avoid_Underflow
843 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
846 else if (word1(rv
) || word0(rv
) & Bndry_mask
) {
847 #ifndef Sudden_Underflow
848 if (word1(rv
) == Tiny1
&& !word0(rv
))
855 /* special case -- power of FLT_RADIX to be */
856 /* rounded down... */
858 if (aadj
< 2./FLT_RADIX
)
867 aadj1
= dsign
? aadj
: -aadj
;
868 #ifdef Check_FLT_ROUNDS
870 case 2: /* towards +infinity */
873 case 0: /* towards 0 */
874 case 3: /* towards -infinity */
880 #endif /*Check_FLT_ROUNDS*/
882 y
= word0(rv
) & Exp_mask
;
884 /* Check for overflow */
886 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
887 dval(rv0
) = dval(rv
);
888 word0(rv
) -= P
*Exp_msk1
;
889 adj
= aadj1
* ulp(dval(rv
));
891 if ((word0(rv
) & Exp_mask
) >=
892 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
893 if (word0(rv0
) == Big0
&& word1(rv0
) == Big1
)
900 word0(rv
) += P
*Exp_msk1
;
903 #ifdef Avoid_Underflow
904 if (scale
&& y
<= 2*P
*Exp_msk1
) {
905 if (aadj
<= 0x7fffffff) {
909 aadj1
= dsign
? aadj
: -aadj
;
911 word0(aadj1
) += (2*P
+1)*Exp_msk1
- y
;
913 adj
= aadj1
* ulp(dval(rv
));
916 #ifdef Sudden_Underflow
917 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
918 dval(rv0
) = dval(rv
);
919 word0(rv
) += P
*Exp_msk1
;
920 adj
= aadj1
* ulp(dval(rv
));
923 if ((word0(rv
) & Exp_mask
) < P
*Exp_msk1
)
925 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
)
928 if (word0(rv0
) == Tiny0
929 && word1(rv0
) == Tiny1
)
936 word0(rv
) -= P
*Exp_msk1
;
939 adj
= aadj1
* ulp(dval(rv
));
942 #else /*Sudden_Underflow*/
943 /* Compute adj so that the IEEE rounding rules will
944 * correctly round rv + adj in some half-way cases.
945 * If rv * ulp(rv) is denormalized (i.e.,
946 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
947 * trouble from bits lost to denormalization;
948 * example: 1.2e-307 .
950 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
951 aadj1
= (double)(int)(aadj
+ 0.5);
955 adj
= aadj1
* ulp(dval(rv
));
957 #endif /*Sudden_Underflow*/
958 #endif /*Avoid_Underflow*/
960 z
= word0(rv
) & Exp_mask
;
962 #ifdef Avoid_Underflow
966 /* Can we stop now? */
969 /* The tolerances below are conservative. */
970 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
) {
971 if (aadj
< .4999999 || aadj
> .5000001)
974 else if (aadj
< .4999999/FLT_RADIX
)
987 word0(rv0
) = Exp_1
+ (70 << Exp_shift
);
992 else if (!oldinexact
)
995 #ifdef Avoid_Underflow
997 word0(rv0
) = Exp_1
- 2*P
*Exp_msk1
;
999 dval(rv
) *= dval(rv0
);
1001 /* try to avoid the bug of testing an 8087 register value */
1002 #if defined(IEEE_Arith) && __DARWIN_UNIX03
1003 if (!(word0(rv
) & Exp_mask
))
1005 if (word0(rv
) == 0 && word1(rv
) == 0)
1010 #endif /* Avoid_Underflow */
1012 if (inexact
&& !(word0(rv
) & Exp_mask
)) {
1013 /* set underflow bit */
1015 dval(rv0
) *= dval(rv0
);
1027 return sign
? -dval(rv
) : dval(rv
);
1033 (s00
, se
) CONST
char *s00
; char **se
;
1035 (CONST
char *s00
, char **se
)
1038 return strtod_l(s00
, se
, __current_locale());