]>
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
42 #define Avoid_Underflow
44 /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
45 /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
46 static CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128,
47 9007199254740992.e
-256
52 #ifdef Honor_FLT_ROUNDS
53 #define Rounding rounding
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
, dsign
,
72 e
, e1
, esign
, i
, j
, k
, nd
, nd0
, nf
, nz
, nz0
, sign
;
73 CONST
char *s
, *s0
, *s1
;
74 double aadj
, aadj1
, adj
, rv
, rv0
;
77 Bigint
*bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
;
79 int inexact
, oldinexact
;
81 #ifdef Honor_FLT_ROUNDS
87 for(s
= s00
;;s
++) switch(*s
) {
111 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
117 switch(i
= gethex(&s
, &fpi
, &exp
, &bb
, sign
)) {
118 case STRTOG_NoNumber
:
124 copybits(bits
, fpi
.nbits
, bb
);
126 ULtod(((U
*)&rv
)->L
, bits
, exp
, i
);
139 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
146 if (c
== *localeconv()->decimal_point
)
153 for(; c
== '0'; c
= *++s
)
155 if (c
> '0' && c
<= '9') {
163 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
168 for(i
= 1; i
< nz
; i
++)
171 else if (nd
<= DBL_DIG
+ 1)
175 else if (nd
<= DBL_DIG
+ 1)
183 if (c
== 'e' || c
== 'E') {
184 if (!nd
&& !nz
&& !nz0
) {
195 if (c
>= '0' && c
<= '9') {
198 if (c
> '0' && c
<= '9') {
201 while((c
= *++s
) >= '0' && c
<= '9')
203 if (s
- s1
> 8 || L
> 19999)
204 /* Avoid confusion from exponents
205 * so large that e might overflow.
207 e
= 19999; /* safe for 16 bit ints */
222 /* Check for Nan and Infinity */
224 static FPI fpinan
= /* only 52 explicit bits */
225 { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
229 if (match(&s
,"nf")) {
231 if (!match(&s
,"inity"))
233 word0(rv
) = 0x7ff00000;
240 if (match(&s
, "an")) {
243 && hexnan(&s
, &fpinan
, bits
)
245 word0(rv
) = 0x7ff00000 | bits
[1];
249 word0(rv
) = NAN_WORD0
;
250 word1(rv
) = NAN_WORD1
;
256 #endif /* INFNAN_CHECK */
265 /* Now we have nd0 digits, starting at s0, followed by a
266 * decimal point, followed by nd-nd0 digits. The number we're
267 * after is the integer represented by those digits times
272 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
277 oldinexact
= get_inexact();
279 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
284 #ifndef Honor_FLT_ROUNDS
296 #ifdef Honor_FLT_ROUNDS
297 /* round correctly FLT_ROUNDS = 2 or 3 */
303 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
308 if (e
<= Ten_pmax
+ i
) {
309 /* A fancier test would sometimes let us do
310 * this for larger i values.
312 #ifdef Honor_FLT_ROUNDS
313 /* round correctly FLT_ROUNDS = 2 or 3 */
322 /* VAX exponent range is so narrow we must
323 * worry about overflow here...
326 word0(rv
) -= P
*Exp_msk1
;
327 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
328 if ((word0(rv
) & Exp_mask
)
329 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
331 word0(rv
) += P
*Exp_msk1
;
333 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
338 #ifndef Inaccurate_Divide
339 else if (e
>= -Ten_pmax
) {
340 #ifdef Honor_FLT_ROUNDS
341 /* round correctly FLT_ROUNDS = 2 or 3 */
347 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
358 oldinexact
= get_inexact();
360 #ifdef Avoid_Underflow
363 #ifdef Honor_FLT_ROUNDS
364 if ((rounding
= Flt_Rounds
) >= 2) {
366 rounding
= rounding
== 2 ? 0 : 2;
372 #endif /*IEEE_Arith*/
374 /* Get starting approximation = rv * 10**e1 */
377 if ( (i
= e1
& 15) !=0)
380 if (e1
> DBL_MAX_10_EXP
) {
385 /* Can't trust HUGE_VAL */
387 #ifdef Honor_FLT_ROUNDS
389 case 0: /* toward 0 */
390 case 3: /* toward -infinity */
395 word0(rv
) = Exp_mask
;
398 #else /*Honor_FLT_ROUNDS*/
399 word0(rv
) = Exp_mask
;
401 #endif /*Honor_FLT_ROUNDS*/
403 /* set overflow bit */
405 dval(rv0
) *= dval(rv0
);
410 #endif /*IEEE_Arith*/
416 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
418 dval(rv
) *= bigtens
[j
];
419 /* The last multiplication could overflow. */
420 word0(rv
) -= P
*Exp_msk1
;
421 dval(rv
) *= bigtens
[j
];
422 if ((z
= word0(rv
) & Exp_mask
)
423 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
425 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
426 /* set to largest number */
427 /* (Can't trust DBL_MAX) */
432 word0(rv
) += P
*Exp_msk1
;
437 if ( (i
= e1
& 15) !=0)
440 if (e1
>= 1 << n_bigtens
)
442 #ifdef Avoid_Underflow
445 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
447 dval(rv
) *= tinytens
[j
];
448 if (scale
&& (j
= 2*P
+ 1 - ((word0(rv
) & Exp_mask
)
449 >> Exp_shift
)) > 0) {
450 /* scaled rv is denormal; zap j low bits */
454 word0(rv
) = (P
+2)*Exp_msk1
;
456 word0(rv
) &= 0xffffffff << j
-32;
459 word1(rv
) &= 0xffffffff << j
;
462 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
464 dval(rv
) *= tinytens
[j
];
465 /* The last multiplication could underflow. */
466 dval(rv0
) = dval(rv
);
467 dval(rv
) *= tinytens
[j
];
469 dval(rv
) = 2.*dval(rv0
);
470 dval(rv
) *= tinytens
[j
];
482 #ifndef Avoid_Underflow
485 /* The refinement below will clean
486 * this approximation up.
493 /* Now the hard part -- adjusting rv to the correct value.*/
495 /* Put digits into bd: true value = bd * 10^e */
497 bd0
= s2b(s0
, nd0
, nd
, y
);
502 bb
= d2b(dval(rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
518 #ifdef Honor_FLT_ROUNDS
522 #ifdef Avoid_Underflow
524 i
= j
+ bbbits
- 1; /* logb(rv) */
525 if (i
< Emin
) /* denormal */
529 #else /*Avoid_Underflow*/
530 #ifdef Sudden_Underflow
532 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
536 #else /*Sudden_Underflow*/
538 i
= j
+ bbbits
- 1; /* logb(rv) */
539 if (i
< Emin
) /* denormal */
543 #endif /*Sudden_Underflow*/
544 #endif /*Avoid_Underflow*/
547 #ifdef Avoid_Underflow
550 i
= bb2
< bd2
? bb2
: bd2
;
559 bs
= pow5mult(bs
, bb5
);
565 bb
= lshift(bb
, bb2
);
567 bd
= pow5mult(bd
, bd5
);
569 bd
= lshift(bd
, bd2
);
571 bs
= lshift(bs
, bs2
);
572 delta
= diff(bb
, bd
);
576 #ifdef Honor_FLT_ROUNDS
579 /* Error is less than an ulp */
580 if (!delta
->x
[0] && delta
->wds
<= 1) {
596 && !(word0(rv
) & Frac_mask
)) {
597 y
= word0(rv
) & Exp_mask
;
598 #ifdef Avoid_Underflow
599 if (!scale
|| y
> 2*P
*Exp_msk1
)
604 delta
= lshift(delta
,Log2P
);
605 if (cmp(delta
, bs
) <= 0)
610 #ifdef Avoid_Underflow
611 if (scale
&& (y
= word0(rv
) & Exp_mask
)
613 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
615 #ifdef Sudden_Underflow
616 if ((word0(rv
) & Exp_mask
) <=
618 word0(rv
) += P
*Exp_msk1
;
619 dval(rv
) += adj
*ulp(dval(rv
));
620 word0(rv
) -= P
*Exp_msk1
;
623 #endif /*Sudden_Underflow*/
624 #endif /*Avoid_Underflow*/
625 dval(rv
) += adj
*ulp(dval(rv
));
629 adj
= ratio(delta
, bs
);
632 if (adj
<= 0x7ffffffe) {
633 /* adj = rounding ? ceil(adj) : floor(adj); */
636 if (!((rounding
>>1) ^ dsign
))
641 #ifdef Avoid_Underflow
642 if (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
643 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
645 #ifdef Sudden_Underflow
646 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
647 word0(rv
) += P
*Exp_msk1
;
648 adj
*= ulp(dval(rv
));
653 word0(rv
) -= P
*Exp_msk1
;
656 #endif /*Sudden_Underflow*/
657 #endif /*Avoid_Underflow*/
658 adj
*= ulp(dval(rv
));
665 #endif /*Honor_FLT_ROUNDS*/
668 /* Error is less than half an ulp -- check for
669 * special case of mantissa a power of two.
671 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
673 #ifdef Avoid_Underflow
674 || (word0(rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
676 || (word0(rv
) & Exp_mask
) <= Exp_msk1
681 if (!delta
->x
[0] && delta
->wds
<= 1)
686 if (!delta
->x
[0] && delta
->wds
<= 1) {
693 delta
= lshift(delta
,Log2P
);
694 if (cmp(delta
, bs
) > 0)
699 /* exactly half-way between */
701 if ((word0(rv
) & Bndry_mask1
) == Bndry_mask1
703 #ifdef Avoid_Underflow
704 (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
705 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
708 /*boundary case -- increment exponent*/
709 word0(rv
) = (word0(rv
) & Exp_mask
)
716 #ifdef Avoid_Underflow
722 else if (!(word0(rv
) & Bndry_mask
) && !word1(rv
)) {
724 /* boundary case -- decrement exponent */
725 #ifdef Sudden_Underflow /*{{*/
726 L
= word0(rv
) & Exp_mask
;
730 #ifdef Avoid_Underflow
731 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
734 #endif /*Avoid_Underflow*/
738 #else /*Sudden_Underflow}{*/
739 #ifdef Avoid_Underflow
741 L
= word0(rv
) & Exp_mask
;
742 if (L
<= (2*P
+1)*Exp_msk1
) {
743 if (L
> (P
+2)*Exp_msk1
)
747 /* rv = smallest denormal */
751 #endif /*Avoid_Underflow*/
752 L
= (word0(rv
) & Exp_mask
) - Exp_msk1
;
753 #endif /*Sudden_Underflow}*/
754 word0(rv
) = L
| Bndry_mask1
;
755 word1(rv
) = 0xffffffff;
763 if (!(word1(rv
) & LSB
))
767 dval(rv
) += ulp(dval(rv
));
770 dval(rv
) -= ulp(dval(rv
));
771 #ifndef Sudden_Underflow
776 #ifdef Avoid_Underflow
782 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
785 else if (word1(rv
) || word0(rv
) & Bndry_mask
) {
786 #ifndef Sudden_Underflow
787 if (word1(rv
) == Tiny1
&& !word0(rv
))
794 /* special case -- power of FLT_RADIX to be */
795 /* rounded down... */
797 if (aadj
< 2./FLT_RADIX
)
806 aadj1
= dsign
? aadj
: -aadj
;
807 #ifdef Check_FLT_ROUNDS
809 case 2: /* towards +infinity */
812 case 0: /* towards 0 */
813 case 3: /* towards -infinity */
819 #endif /*Check_FLT_ROUNDS*/
821 y
= word0(rv
) & Exp_mask
;
823 /* Check for overflow */
825 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
826 dval(rv0
) = dval(rv
);
827 word0(rv
) -= P
*Exp_msk1
;
828 adj
= aadj1
* ulp(dval(rv
));
830 if ((word0(rv
) & Exp_mask
) >=
831 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
832 if (word0(rv0
) == Big0
&& word1(rv0
) == Big1
)
839 word0(rv
) += P
*Exp_msk1
;
842 #ifdef Avoid_Underflow
843 if (scale
&& y
<= 2*P
*Exp_msk1
) {
844 if (aadj
<= 0x7fffffff) {
848 aadj1
= dsign
? aadj
: -aadj
;
850 word0(aadj1
) += (2*P
+1)*Exp_msk1
- y
;
852 adj
= aadj1
* ulp(dval(rv
));
855 #ifdef Sudden_Underflow
856 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
857 dval(rv0
) = dval(rv
);
858 word0(rv
) += P
*Exp_msk1
;
859 adj
= aadj1
* ulp(dval(rv
));
862 if ((word0(rv
) & Exp_mask
) < P
*Exp_msk1
)
864 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
)
867 if (word0(rv0
) == Tiny0
868 && word1(rv0
) == Tiny1
)
875 word0(rv
) -= P
*Exp_msk1
;
878 adj
= aadj1
* ulp(dval(rv
));
881 #else /*Sudden_Underflow*/
882 /* Compute adj so that the IEEE rounding rules will
883 * correctly round rv + adj in some half-way cases.
884 * If rv * ulp(rv) is denormalized (i.e.,
885 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
886 * trouble from bits lost to denormalization;
887 * example: 1.2e-307 .
889 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
890 aadj1
= (double)(int)(aadj
+ 0.5);
894 adj
= aadj1
* ulp(dval(rv
));
896 #endif /*Sudden_Underflow*/
897 #endif /*Avoid_Underflow*/
899 z
= word0(rv
) & Exp_mask
;
901 #ifdef Avoid_Underflow
905 /* Can we stop now? */
908 /* The tolerances below are conservative. */
909 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
) {
910 if (aadj
< .4999999 || aadj
> .5000001)
913 else if (aadj
< .4999999/FLT_RADIX
)
926 word0(rv0
) = Exp_1
+ (70 << Exp_shift
);
931 else if (!oldinexact
)
934 #ifdef Avoid_Underflow
936 word0(rv0
) = Exp_1
- 2*P
*Exp_msk1
;
938 dval(rv
) *= dval(rv0
);
940 /* try to avoid the bug of testing an 8087 register value */
941 if (word0(rv
) == 0 && word1(rv
) == 0)
945 #endif /* Avoid_Underflow */
947 if (inexact
&& !(word0(rv
) & Exp_mask
)) {
948 /* set underflow bit */
950 dval(rv0
) *= dval(rv0
);
962 return sign
? -dval(rv
) : dval(rv
);