]>
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^53 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.e
-256
55 #ifdef Honor_FLT_ROUNDS
56 #define Rounding rounding
57 #undef Check_FLT_ROUNDS
58 #define Check_FLT_ROUNDS
60 #define Rounding Flt_Rounds
66 (s00
, se
, loc
) CONST
char *s00
; char **se
; locale_t loc
;
68 (CONST
char *s00
, char **se
, locale_t loc
)
71 #ifdef Avoid_Underflow
74 int bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, dsign
,
75 e
, e1
, esign
, i
, j
, k
, nd
, nd0
, nf
, nz
, nz0
, sign
;
76 CONST
char *s
, *s0
, *s1
;
77 double aadj
, aadj1
, adj
, rv
, rv0
;
80 Bigint
*bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
;
82 int inexact
, oldinexact
;
84 #ifdef Honor_FLT_ROUNDS
85 int rounding
= Flt_Rounds
;
89 int decimal_point_len
;
90 #endif /* USE_LOCALE */
92 sign
= nz0
= nz
= decpt
= 0;
94 for(s
= s00
;;s
++) switch(*s
) {
118 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
125 #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
127 switch(fegetround()) {
128 case FE_TOWARDZERO
: fpi1
.rounding
= 0; break;
129 case FE_UPWARD
: fpi1
.rounding
= 2; break;
130 case FE_DOWNWARD
: fpi1
.rounding
= 3;
135 switch((i
= gethex(&s
, &fpi1
, &exp
, &bb
, sign
, loc
)) & STRTOG_Retmask
) {
136 case STRTOG_NoNumber
:
143 copybits(bits
, fpi
.nbits
, bb
);
146 ULtod(((U
*)&rv
)->L
, bits
, exp
, i
);
159 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
165 NORMALIZE_LOCALE(loc
);
167 decimal_point
= localeconv_l(loc
)->decimal_point
;
168 decimal_point_len
= strlen(decimal_point
);
169 if (strncmp(s
, decimal_point
, decimal_point_len
) == 0)
176 s
+= decimal_point_len
;
182 for(; c
== '0'; c
= *++s
)
184 if (c
> '0' && c
<= '9') {
192 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
197 for(i
= 1; i
< nz
; i
++)
200 else if (nd
<= DBL_DIG
+ 1)
204 else if (nd
<= DBL_DIG
+ 1)
212 if (c
== 'e' || c
== 'E') {
213 if (!nd
&& !nz
&& !nz0
) {
224 if (c
>= '0' && c
<= '9') {
227 if (c
> '0' && c
<= '9') {
230 while((c
= *++s
) >= '0' && c
<= '9')
232 if (s
- s1
> 8 || L
> 19999)
233 /* Avoid confusion from exponents
234 * so large that e might overflow.
236 e
= 19999; /* safe for 16 bit ints */
251 /* Check for Nan and Infinity */
253 static FPI fpinan
= /* only 52 explicit bits */
254 { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
259 if (match(&s
,"nf")) {
261 if (!match(&s
,"inity"))
263 word0(rv
) = 0x7ff00000;
270 if (match(&s
, "an")) {
273 && hexnan(&s
, &fpinan
, bits
)
275 word0(rv
) = 0x7ff00000 | bits
[1];
280 word0(rv
) = NAN_WORD0
;
281 word1(rv
) = NAN_WORD1
;
288 #endif /* INFNAN_CHECK */
297 /* Now we have nd0 digits, starting at s0, followed by a
298 * decimal point, followed by nd-nd0 digits. The number we're
299 * after is the integer represented by those digits times
304 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
309 oldinexact
= get_inexact();
311 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
316 #ifndef Honor_FLT_ROUNDS
328 #ifdef Honor_FLT_ROUNDS
329 /* round correctly FLT_ROUNDS = 2 or 3 */
335 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
340 if (e
<= Ten_pmax
+ i
) {
341 /* A fancier test would sometimes let us do
342 * this for larger i values.
344 #ifdef Honor_FLT_ROUNDS
345 /* round correctly FLT_ROUNDS = 2 or 3 */
354 /* VAX exponent range is so narrow we must
355 * worry about overflow here...
358 word0(rv
) -= P
*Exp_msk1
;
359 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
360 if ((word0(rv
) & Exp_mask
)
361 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
363 word0(rv
) += P
*Exp_msk1
;
365 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
370 #ifndef Inaccurate_Divide
371 else if (e
>= -Ten_pmax
) {
372 #ifdef Honor_FLT_ROUNDS
373 /* round correctly FLT_ROUNDS = 2 or 3 */
379 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
390 oldinexact
= get_inexact();
392 #ifdef Avoid_Underflow
395 #ifdef Honor_FLT_ROUNDS
398 rounding
= rounding
== 2 ? 0 : 2;
404 #endif /*IEEE_Arith*/
406 /* Get starting approximation = rv * 10**e1 */
409 if ( (i
= e1
& 15) !=0)
412 if (e1
> DBL_MAX_10_EXP
) {
417 /* Can't trust HUGE_VAL */
419 #ifdef Honor_FLT_ROUNDS
421 case 0: /* toward 0 */
422 case 3: /* toward -infinity */
427 word0(rv
) = Exp_mask
;
430 #else /*Honor_FLT_ROUNDS*/
431 word0(rv
) = Exp_mask
;
433 #endif /*Honor_FLT_ROUNDS*/
435 /* set overflow bit */
437 dval(rv0
) *= dval(rv0
);
442 #endif /*IEEE_Arith*/
448 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
450 dval(rv
) *= bigtens
[j
];
451 /* The last multiplication could overflow. */
452 word0(rv
) -= P
*Exp_msk1
;
453 dval(rv
) *= bigtens
[j
];
454 if ((z
= word0(rv
) & Exp_mask
)
455 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
457 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
458 /* set to largest number */
459 /* (Can't trust DBL_MAX) */
464 word0(rv
) += P
*Exp_msk1
;
469 if ( (i
= e1
& 15) !=0)
472 if (e1
>= 1 << n_bigtens
)
474 #ifdef Avoid_Underflow
477 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
479 dval(rv
) *= tinytens
[j
];
480 if (scale
&& (j
= 2*P
+ 1 - ((word0(rv
) & Exp_mask
)
481 >> Exp_shift
)) > 0) {
482 /* scaled rv is denormal; zap j low bits */
486 word0(rv
) = (P
+2)*Exp_msk1
;
488 word0(rv
) &= 0xffffffff << j
-32;
491 word1(rv
) &= 0xffffffff << j
;
494 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
496 dval(rv
) *= tinytens
[j
];
497 /* The last multiplication could underflow. */
498 dval(rv0
) = dval(rv
);
499 dval(rv
) *= tinytens
[j
];
501 dval(rv
) = 2.*dval(rv0
);
502 dval(rv
) *= tinytens
[j
];
514 #ifndef Avoid_Underflow
517 /* The refinement below will clean
518 * this approximation up.
525 /* Now the hard part -- adjusting rv to the correct value.*/
527 /* Put digits into bd: true value = bd * 10^e */
530 bd0
= s2b(s0
, nd0
, nd
, y
, decimal_point_len
);
532 bd0
= s2b(s0
, nd0
, nd
, y
, 1);
538 bb
= d2b(dval(rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
554 #ifdef Honor_FLT_ROUNDS
558 #ifdef Avoid_Underflow
560 i
= j
+ bbbits
- 1; /* logb(rv) */
561 if (i
< Emin
) /* denormal */
565 #else /*Avoid_Underflow*/
566 #ifdef Sudden_Underflow
568 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
572 #else /*Sudden_Underflow*/
574 i
= j
+ bbbits
- 1; /* logb(rv) */
575 if (i
< Emin
) /* denormal */
579 #endif /*Sudden_Underflow*/
580 #endif /*Avoid_Underflow*/
583 #ifdef Avoid_Underflow
586 i
= bb2
< bd2
? bb2
: bd2
;
595 bs
= pow5mult(bs
, bb5
);
601 bb
= lshift(bb
, bb2
);
603 bd
= pow5mult(bd
, bd5
);
605 bd
= lshift(bd
, bd2
);
607 bs
= lshift(bs
, bs2
);
608 delta
= diff(bb
, bd
);
612 #ifdef Honor_FLT_ROUNDS
615 /* Error is less than an ulp */
616 if (!delta
->x
[0] && delta
->wds
<= 1) {
632 && !(word0(rv
) & Frac_mask
)) {
633 y
= word0(rv
) & Exp_mask
;
634 #ifdef Avoid_Underflow
635 if (!scale
|| y
> 2*P
*Exp_msk1
)
640 delta
= lshift(delta
,Log2P
);
641 if (cmp(delta
, bs
) <= 0)
646 #ifdef Avoid_Underflow
647 if (scale
&& (y
= word0(rv
) & Exp_mask
)
649 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
651 #ifdef Sudden_Underflow
652 if ((word0(rv
) & Exp_mask
) <=
654 word0(rv
) += P
*Exp_msk1
;
655 dval(rv
) += adj
*ulp(dval(rv
));
656 word0(rv
) -= P
*Exp_msk1
;
659 #endif /*Sudden_Underflow*/
660 #endif /*Avoid_Underflow*/
661 dval(rv
) += adj
*ulp(dval(rv
));
665 adj
= ratio(delta
, bs
);
668 if (adj
<= 0x7ffffffe) {
669 /* adj = rounding ? ceil(adj) : floor(adj); */
672 if (!((rounding
>>1) ^ dsign
))
677 #ifdef Avoid_Underflow
678 if (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
679 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
681 #ifdef Sudden_Underflow
682 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
683 word0(rv
) += P
*Exp_msk1
;
684 adj
*= ulp(dval(rv
));
689 word0(rv
) -= P
*Exp_msk1
;
692 #endif /*Sudden_Underflow*/
693 #endif /*Avoid_Underflow*/
694 adj
*= ulp(dval(rv
));
701 #endif /*Honor_FLT_ROUNDS*/
704 /* Error is less than half an ulp -- check for
705 * special case of mantissa a power of two.
707 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
709 #ifdef Avoid_Underflow
710 || (word0(rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
712 || (word0(rv
) & Exp_mask
) <= Exp_msk1
717 if (!delta
->x
[0] && delta
->wds
<= 1)
722 if (!delta
->x
[0] && delta
->wds
<= 1) {
729 delta
= lshift(delta
,Log2P
);
730 if (cmp(delta
, bs
) > 0)
735 /* exactly half-way between */
737 if ((word0(rv
) & Bndry_mask1
) == Bndry_mask1
739 #ifdef Avoid_Underflow
740 (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
741 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
744 /*boundary case -- increment exponent*/
745 word0(rv
) = (word0(rv
) & Exp_mask
)
752 #ifdef Avoid_Underflow
758 else if (!(word0(rv
) & Bndry_mask
) && !word1(rv
)) {
760 /* boundary case -- decrement exponent */
761 #ifdef Sudden_Underflow /*{{*/
762 L
= word0(rv
) & Exp_mask
;
766 #ifdef Avoid_Underflow
767 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
770 #endif /*Avoid_Underflow*/
774 #else /*Sudden_Underflow}{*/
775 #ifdef Avoid_Underflow
777 L
= word0(rv
) & Exp_mask
;
778 if (L
<= (2*P
+1)*Exp_msk1
) {
779 if (L
> (P
+2)*Exp_msk1
)
783 /* rv = smallest denormal */
787 #endif /*Avoid_Underflow*/
788 L
= (word0(rv
) & Exp_mask
) - Exp_msk1
;
789 #endif /*Sudden_Underflow}*/
790 word0(rv
) = L
| Bndry_mask1
;
791 word1(rv
) = 0xffffffff;
799 if (!(word1(rv
) & LSB
))
803 dval(rv
) += ulp(dval(rv
));
806 dval(rv
) -= ulp(dval(rv
));
807 #ifndef Sudden_Underflow
812 #ifdef Avoid_Underflow
818 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
821 else if (word1(rv
) || word0(rv
) & Bndry_mask
) {
822 #ifndef Sudden_Underflow
823 if (word1(rv
) == Tiny1
&& !word0(rv
))
830 /* special case -- power of FLT_RADIX to be */
831 /* rounded down... */
833 if (aadj
< 2./FLT_RADIX
)
842 aadj1
= dsign
? aadj
: -aadj
;
843 #ifdef Check_FLT_ROUNDS
845 case 2: /* towards +infinity */
848 case 0: /* towards 0 */
849 case 3: /* towards -infinity */
855 #endif /*Check_FLT_ROUNDS*/
857 y
= word0(rv
) & Exp_mask
;
859 /* Check for overflow */
861 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
862 dval(rv0
) = dval(rv
);
863 word0(rv
) -= P
*Exp_msk1
;
864 adj
= aadj1
* ulp(dval(rv
));
866 if ((word0(rv
) & Exp_mask
) >=
867 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
868 if (word0(rv0
) == Big0
&& word1(rv0
) == Big1
)
875 word0(rv
) += P
*Exp_msk1
;
878 #ifdef Avoid_Underflow
879 if (scale
&& y
<= 2*P
*Exp_msk1
) {
880 if (aadj
<= 0x7fffffff) {
884 aadj1
= dsign
? aadj
: -aadj
;
886 word0(aadj1
) += (2*P
+1)*Exp_msk1
- y
;
888 adj
= aadj1
* ulp(dval(rv
));
891 #ifdef Sudden_Underflow
892 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
893 dval(rv0
) = dval(rv
);
894 word0(rv
) += P
*Exp_msk1
;
895 adj
= aadj1
* ulp(dval(rv
));
898 if ((word0(rv
) & Exp_mask
) < P
*Exp_msk1
)
900 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
)
903 if (word0(rv0
) == Tiny0
904 && word1(rv0
) == Tiny1
)
911 word0(rv
) -= P
*Exp_msk1
;
914 adj
= aadj1
* ulp(dval(rv
));
917 #else /*Sudden_Underflow*/
918 /* Compute adj so that the IEEE rounding rules will
919 * correctly round rv + adj in some half-way cases.
920 * If rv * ulp(rv) is denormalized (i.e.,
921 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
922 * trouble from bits lost to denormalization;
923 * example: 1.2e-307 .
925 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
926 aadj1
= (double)(int)(aadj
+ 0.5);
930 adj
= aadj1
* ulp(dval(rv
));
932 #endif /*Sudden_Underflow*/
933 #endif /*Avoid_Underflow*/
935 z
= word0(rv
) & Exp_mask
;
937 #ifdef Avoid_Underflow
941 /* Can we stop now? */
944 /* The tolerances below are conservative. */
945 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
) {
946 if (aadj
< .4999999 || aadj
> .5000001)
949 else if (aadj
< .4999999/FLT_RADIX
)
962 word0(rv0
) = Exp_1
+ (70 << Exp_shift
);
967 else if (!oldinexact
)
970 #ifdef Avoid_Underflow
972 word0(rv0
) = Exp_1
- 2*P
*Exp_msk1
;
974 dval(rv
) *= dval(rv0
);
976 /* try to avoid the bug of testing an 8087 register value */
978 if (word0(rv
) == 0 && word1(rv
) == 0 || dval(rv
) < DBL_MIN
)
979 #else /* !__DARWIN_UNIX03 */
980 if (word0(rv
) == 0 && word1(rv
) == 0)
981 #endif /* __DARWIN_UNIX03 */
985 #endif /* Avoid_Underflow */
987 if (inexact
&& !(word0(rv
) & Exp_mask
)) {
988 /* set underflow bit */
990 dval(rv0
) *= dval(rv0
);
1002 return sign
? -dval(rv
) : dval(rv
);
1008 (s00
, se
) CONST
char *s00
; char **se
;
1010 (CONST
char *s00
, char **se
)
1013 return strtod_l(s00
, se
, __current_locale());