1 /* $NetBSD: strtod.c,v 1.4 2006/06/02 19:46:56 mrg Exp $ */
3 /****************************************************************
5 The author of this software is David M. Gay.
7 Copyright (C) 1998-2001 by Lucent Technologies
10 Permission to use, copy, modify, and distribute this software and
11 its documentation for any purpose and without fee is hereby
12 granted, provided that the above copyright notice appear in all
13 copies and that both that the copyright notice and this
14 permission notice and warranty disclaimer appear in supporting
15 documentation, and that the name of Lucent or any of its entities
16 not be used in advertising or publicity pertaining to
17 distribution of the software without specific, written prior
20 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
22 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
23 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
25 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
29 ****************************************************************/
31 /* Please send bug reports to David M. Gay (dmg at acm dot org,
32 * with " at " changed at "@" and " dot " changed to "."). */
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
63 #ifndef __HAVE_LONG_DOUBLE
64 __strong_alias(_strtold
, strtod
)
65 __weak_alias(strtold
, _strtold
)
71 (s00
, se
) CONST
char *s00
; char **se
;
73 (CONST
char *s00
, char **se
)
76 #ifdef Avoid_Underflow
79 int bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, dsign
,
80 e
, e1
, esign
, i
, j
, k
, nd
, nd0
, nf
, nz
, nz0
, sign
;
81 CONST
char *s
, *s0
, *s1
;
82 double aadj
, aadj1
, adj
, rv
, rv0
;
85 Bigint
*bb
= NULL
, *bb1
, *bd0
;
86 Bigint
*bd
= NULL
, *bs
= NULL
, *delta
= NULL
; /* pacify gcc */
88 int inexact
, oldinexact
;
90 #ifdef Honor_FLT_ROUNDS
94 sign
= nz0
= nz
= decpt
= 0;
96 for(s
= s00
;;s
++) switch(*s
) {
120 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
127 #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
129 switch(fegetround()) {
130 case FE_TOWARDZERO
: fpi1
.rounding
= 0; break;
131 case FE_UPWARD
: fpi1
.rounding
= 2; break;
132 case FE_DOWNWARD
: fpi1
.rounding
= 3;
137 switch((i
= gethex(&s
, &fpi1
, &expt
, &bb
, sign
)) & STRTOG_Retmask
) {
138 case STRTOG_NoNumber
:
146 copybits(bits
, fpi
.nbits
, bb
);
149 ULtod((/* LINTED */(U
*)&rv
)->L
, bits
, expt
, i
);
162 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
169 if (c
== *localeconv()->decimal_point
)
177 for(; c
== '0'; c
= *++s
)
179 if (c
> '0' && c
<= '9') {
187 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
192 for(i
= 1; i
< nz
; i
++)
195 else if (nd
<= DBL_DIG
+ 1)
199 else if (nd
<= DBL_DIG
+ 1)
207 if (c
== 'e' || c
== 'E') {
208 if (!nd
&& !nz
&& !nz0
) {
220 if (c
>= '0' && c
<= '9') {
223 if (c
> '0' && c
<= '9') {
226 while((c
= *++s
) >= '0' && c
<= '9')
228 if (s
- s1
> 8 || L
> 19999)
229 /* Avoid confusion from exponents
230 * so large that e might overflow.
232 e
= 19999; /* safe for 16 bit ints */
247 /* Check for Nan and Infinity */
249 static FPI fpinan
= /* only 52 explicit bits */
250 { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
255 if (match(&s
,"nf")) {
257 if (!match(&s
,"inity"))
259 word0(rv
) = 0x7ff00000;
266 if (match(&s
, "an")) {
269 && hexnan(&s
, &fpinan
, bits
)
271 word0(rv
) = 0x7ff00000 | bits
[1];
276 word0(rv
) = NAN_WORD0
;
277 word1(rv
) = NAN_WORD1
;
284 #endif /* INFNAN_CHECK */
293 /* Now we have nd0 digits, starting at s0, followed by a
294 * decimal point, followed by nd-nd0 digits. The number we're
295 * after is the integer represented by those digits times
300 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
305 oldinexact
= get_inexact();
307 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
312 #ifndef Honor_FLT_ROUNDS
324 #ifdef Honor_FLT_ROUNDS
325 /* round correctly FLT_ROUNDS = 2 or 3 */
331 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
336 if (e
<= Ten_pmax
+ i
) {
337 /* A fancier test would sometimes let us do
338 * this for larger i values.
340 #ifdef Honor_FLT_ROUNDS
341 /* round correctly FLT_ROUNDS = 2 or 3 */
350 /* VAX exponent range is so narrow we must
351 * worry about overflow here...
354 word0(rv
) -= P
*Exp_msk1
;
355 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
356 if ((word0(rv
) & Exp_mask
)
357 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
359 word0(rv
) += P
*Exp_msk1
;
361 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
366 #ifndef Inaccurate_Divide
367 else if (e
>= -Ten_pmax
) {
368 #ifdef Honor_FLT_ROUNDS
369 /* round correctly FLT_ROUNDS = 2 or 3 */
375 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
386 oldinexact
= get_inexact();
388 #ifdef Avoid_Underflow
391 #ifdef Honor_FLT_ROUNDS
392 if ((rounding
= Flt_Rounds
) >= 2) {
394 rounding
= rounding
== 2 ? 0 : 2;
400 #endif /*IEEE_Arith*/
402 /* Get starting approximation = rv * 10**e1 */
405 if ( (i
= e1
& 15) !=0)
408 if (e1
> DBL_MAX_10_EXP
) {
413 /* Can't trust HUGE_VAL */
415 #ifdef Honor_FLT_ROUNDS
417 case 0: /* toward 0 */
418 case 3: /* toward -infinity */
423 word0(rv
) = Exp_mask
;
426 #else /*Honor_FLT_ROUNDS*/
427 word0(rv
) = Exp_mask
;
429 #endif /*Honor_FLT_ROUNDS*/
431 /* set overflow bit */
433 dval(rv0
) *= dval(rv0
);
438 #endif /*IEEE_Arith*/
443 e1
= (unsigned int)e1
>> 4;
444 for(j
= 0; e1
> 1; j
++, e1
= (unsigned int)e1
>> 1)
446 dval(rv
) *= bigtens
[j
];
447 /* The last multiplication could overflow. */
448 word0(rv
) -= P
*Exp_msk1
;
449 dval(rv
) *= bigtens
[j
];
450 if ((z
= word0(rv
) & Exp_mask
)
451 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
453 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
454 /* set to largest number */
455 /* (Can't trust DBL_MAX) */
460 word0(rv
) += P
*Exp_msk1
;
465 if ( (i
= e1
& 15) !=0)
468 if (e1
>= 1 << n_bigtens
)
470 #ifdef Avoid_Underflow
473 for(j
= 0; e1
> 0; j
++, e1
= (unsigned int)e1
>> 1)
475 dval(rv
) *= tinytens
[j
];
476 if (scale
&& (j
= 2*P
+ 1 - ((word0(rv
) & Exp_mask
)
477 >> Exp_shift
)) > 0) {
478 /* scaled rv is denormal; zap j low bits */
482 word0(rv
) = (P
+2)*Exp_msk1
;
484 word0(rv
) &= 0xffffffff << (j
-32);
487 word1(rv
) &= 0xffffffff << j
;
490 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
492 dval(rv
) *= tinytens
[j
];
493 /* The last multiplication could underflow. */
494 dval(rv0
) = dval(rv
);
495 dval(rv
) *= tinytens
[j
];
497 dval(rv
) = 2.*dval(rv0
);
498 dval(rv
) *= tinytens
[j
];
510 #ifndef Avoid_Underflow
513 /* The refinement below will clean
514 * this approximation up.
521 /* Now the hard part -- adjusting rv to the correct value.*/
523 /* Put digits into bd: true value = bd * 10^e */
525 bd0
= s2b(s0
, nd0
, nd
, y
);
534 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
);
605 bb
= lshift(bb
, bb2
);
610 bd
= pow5mult(bd
, bd5
);
615 bd
= lshift(bd
, bd2
);
620 bs
= lshift(bs
, bs2
);
624 delta
= diff(bb
, bd
);
630 #ifdef Honor_FLT_ROUNDS
633 /* Error is less than an ulp */
634 if (!delta
->x
[0] && delta
->wds
<= 1) {
650 && !(word0(rv
) & Frac_mask
)) {
651 y
= word0(rv
) & Exp_mask
;
652 #ifdef Avoid_Underflow
653 if (!scale
|| y
> 2*P
*Exp_msk1
)
658 delta
= lshift(delta
,Log2P
);
659 if (cmp(delta
, bs
) <= 0)
664 #ifdef Avoid_Underflow
665 if (scale
&& (y
= word0(rv
) & Exp_mask
)
667 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
669 #ifdef Sudden_Underflow
670 if ((word0(rv
) & Exp_mask
) <=
672 word0(rv
) += P
*Exp_msk1
;
673 dval(rv
) += adj
*ulp(dval(rv
));
674 word0(rv
) -= P
*Exp_msk1
;
677 #endif /*Sudden_Underflow*/
678 #endif /*Avoid_Underflow*/
679 dval(rv
) += adj
*ulp(dval(rv
));
683 adj
= ratio(delta
, bs
);
686 if (adj
<= 0x7ffffffe) {
687 /* adj = rounding ? ceil(adj) : floor(adj); */
690 if (!((rounding
>>1) ^ dsign
))
695 #ifdef Avoid_Underflow
696 if (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
697 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
699 #ifdef Sudden_Underflow
700 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
701 word0(rv
) += P
*Exp_msk1
;
702 adj
*= ulp(dval(rv
));
707 word0(rv
) -= P
*Exp_msk1
;
710 #endif /*Sudden_Underflow*/
711 #endif /*Avoid_Underflow*/
712 adj
*= ulp(dval(rv
));
719 #endif /*Honor_FLT_ROUNDS*/
722 /* Error is less than half an ulp -- check for
723 * special case of mantissa a power of two.
725 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
727 #ifdef Avoid_Underflow
728 || (word0(rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
730 || (word0(rv
) & Exp_mask
) <= Exp_msk1
735 if (!delta
->x
[0] && delta
->wds
<= 1)
740 if (!delta
->x
[0] && delta
->wds
<= 1) {
747 delta
= lshift(delta
,Log2P
);
748 if (cmp(delta
, bs
) > 0)
753 /* exactly half-way between */
755 if ((word0(rv
) & Bndry_mask1
) == Bndry_mask1
757 #ifdef Avoid_Underflow
758 (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
759 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
762 /*boundary case -- increment exponent*/
763 word0(rv
) = (word0(rv
) & Exp_mask
)
770 #ifdef Avoid_Underflow
776 else if (!(word0(rv
) & Bndry_mask
) && !word1(rv
)) {
778 /* boundary case -- decrement exponent */
779 #ifdef Sudden_Underflow /*{{*/
780 L
= word0(rv
) & Exp_mask
;
784 #ifdef Avoid_Underflow
785 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
788 #endif /*Avoid_Underflow*/
792 #else /*Sudden_Underflow}{*/
793 #ifdef Avoid_Underflow
795 L
= word0(rv
) & Exp_mask
;
796 if (L
<= (2*P
+1)*Exp_msk1
) {
797 if (L
> (P
+2)*Exp_msk1
)
801 /* rv = smallest denormal */
805 #endif /*Avoid_Underflow*/
806 L
= (word0(rv
) & Exp_mask
) - Exp_msk1
;
807 #endif /*Sudden_Underflow}*/
808 word0(rv
) = L
| Bndry_mask1
;
809 word1(rv
) = 0xffffffff;
817 if (!(word1(rv
) & LSB
))
821 dval(rv
) += ulp(dval(rv
));
824 dval(rv
) -= ulp(dval(rv
));
825 #ifndef Sudden_Underflow
830 #ifdef Avoid_Underflow
836 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
839 else if (word1(rv
) || word0(rv
) & Bndry_mask
) {
840 #ifndef Sudden_Underflow
841 if (word1(rv
) == Tiny1
&& !word0(rv
))
848 /* special case -- power of FLT_RADIX to be */
849 /* rounded down... */
851 if (aadj
< 2./FLT_RADIX
)
860 aadj1
= dsign
? aadj
: -aadj
;
861 #ifdef Check_FLT_ROUNDS
863 case 2: /* towards +infinity */
866 case 0: /* towards 0 */
867 case 3: /* towards -infinity */
873 #endif /*Check_FLT_ROUNDS*/
875 y
= word0(rv
) & Exp_mask
;
877 /* Check for overflow */
879 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
880 dval(rv0
) = dval(rv
);
881 word0(rv
) -= P
*Exp_msk1
;
882 adj
= aadj1
* ulp(dval(rv
));
884 if ((word0(rv
) & Exp_mask
) >=
885 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
886 if (word0(rv0
) == Big0
&& word1(rv0
) == Big1
)
893 word0(rv
) += P
*Exp_msk1
;
896 #ifdef Avoid_Underflow
897 if (scale
&& y
<= 2*P
*Exp_msk1
) {
898 if (aadj
<= 0x7fffffff) {
902 aadj1
= dsign
? aadj
: -aadj
;
904 word0(aadj1
) += (2*P
+1)*Exp_msk1
- y
;
906 adj
= aadj1
* ulp(dval(rv
));
909 #ifdef Sudden_Underflow
910 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
911 dval(rv0
) = dval(rv
);
912 word0(rv
) += P
*Exp_msk1
;
913 adj
= aadj1
* ulp(dval(rv
));
916 if ((word0(rv
) & Exp_mask
) < P
*Exp_msk1
)
918 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
)
921 if (word0(rv0
) == Tiny0
922 && word1(rv0
) == Tiny1
)
929 word0(rv
) -= P
*Exp_msk1
;
932 adj
= aadj1
* ulp(dval(rv
));
935 #else /*Sudden_Underflow*/
936 /* Compute adj so that the IEEE rounding rules will
937 * correctly round rv + adj in some half-way cases.
938 * If rv * ulp(rv) is denormalized (i.e.,
939 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
940 * trouble from bits lost to denormalization;
941 * example: 1.2e-307 .
943 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
944 aadj1
= (double)(int)(aadj
+ 0.5);
948 adj
= aadj1
* ulp(dval(rv
));
950 #endif /*Sudden_Underflow*/
951 #endif /*Avoid_Underflow*/
953 z
= word0(rv
) & Exp_mask
;
955 #ifdef Avoid_Underflow
959 /* Can we stop now? */
962 /* The tolerances below are conservative. */
963 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
) {
964 if (aadj
< .4999999 || aadj
> .5000001)
967 else if (aadj
< .4999999/FLT_RADIX
)
980 word0(rv0
) = Exp_1
+ (70 << Exp_shift
);
985 else if (!oldinexact
)
988 #ifdef Avoid_Underflow
990 word0(rv0
) = Exp_1
- 2*P
*Exp_msk1
;
992 dval(rv
) *= dval(rv0
);
994 /* try to avoid the bug of testing an 8087 register value */
995 if (word0(rv
) == 0 && word1(rv
) == 0)
999 #endif /* Avoid_Underflow */
1001 if (inexact
&& !(word0(rv
) & Exp_mask
)) {
1002 /* set underflow bit */
1004 dval(rv0
) *= dval(rv0
);
1016 return sign
? -dval(rv
) : dval(rv
);