]>
git.proxmox.com Git - mirror_edk2.git/blob - StdLib/LibC/gdtoa/strtod.c
1 /* $NetBSD: strtod.c,v 1.4.14.1 2008/04/08 21:10:55 jdc 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 "."). */
33 #include <LibConfig.h>
46 #define Avoid_Underflow
48 /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
49 /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
50 static CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128,
51 9007199254740992.e
-256
56 #ifdef Honor_FLT_ROUNDS
57 #define Rounding rounding
58 #undef Check_FLT_ROUNDS
59 #define Check_FLT_ROUNDS
61 #define Rounding Flt_Rounds
64 //#ifndef __HAVE_LONG_DOUBLE
65 //__strong_alias(_strtold, strtod)
66 //__weak_alias(strtold, _strtold)
69 #if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
70 // Disable: warning C4700: uninitialized local variable 'xx' used
71 #pragma warning ( disable : 4700 )
72 #endif /* defined(_MSC_VER) */
75 strtod(CONST
char *s00
, char **se
)
77 #ifdef Avoid_Underflow
80 int bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, dsign
,
81 e
, e1
, esign
, i
, j
, k
, nd
, nd0
, nf
, nz
, nz0
, sign
;
82 CONST
char *s
, *s0
, *s1
;
83 double aadj
, aadj1
, adj
, rv
, rv0
;
86 Bigint
*bb
= NULL
, *bb1
, *bd0
;
87 Bigint
*bd
= NULL
, *bs
= NULL
, *delta
= NULL
; /* pacify gcc */
89 int inexact
, oldinexact
;
91 #ifdef Honor_FLT_ROUNDS
95 sign
= nz0
= nz
= decpt
= 0;
123 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
130 #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
132 switch(fegetround()) {
133 case FE_TOWARDZERO
: fpi1
.rounding
= 0; break;
134 case FE_UPWARD
: fpi1
.rounding
= 2; break;
135 case FE_DOWNWARD
: fpi1
.rounding
= 3;
139 switch((i
= gethex(&s
, &fpi
, &expt
, &bb
, sign
)) & STRTOG_Retmask
) {
140 case STRTOG_NoNumber
:
148 copybits(bits
, fpi
.nbits
, bb
);
151 ULtod((/* LINTED */(U
*)&rv
)->L
, bits
, expt
, i
);
164 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
171 if (c
== *localeconv()->decimal_point
)
179 for(; c
== '0'; c
= *++s
)
181 if (c
> '0' && c
<= '9') {
189 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
194 for(i
= 1; i
< nz
; i
++)
197 else if (nd
<= DBL_DIG
+ 1)
201 else if (nd
<= DBL_DIG
+ 1)
209 if (c
== 'e' || c
== 'E') {
210 if (!nd
&& !nz
&& !nz0
) {
222 if (c
>= '0' && c
<= '9') {
225 if (c
> '0' && c
<= '9') {
228 while((c
= *++s
) >= '0' && c
<= '9')
230 if (s
- s1
> 8 || L
> 19999)
231 /* Avoid confusion from exponents
232 * so large that e might overflow.
234 e
= 19999; /* safe for 16 bit ints */
249 /* Check for Nan and Infinity */
252 static FPI fpinan
= /* only 52 explicit bits */
253 { 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
) = (UINT32
)(0x7ff00000U
| bits
[1]);
276 word1(rv
) = (UINT32
)bits
[0];
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;
305 dval(rv
) = (double)y
;
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
396 if ((rounding
= Flt_Rounds
) >= 2) {
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*/
447 e1
= (unsigned int)e1
>> 4;
448 for(j
= 0; e1
> 1; j
++, e1
= (unsigned int)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
= (unsigned int)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 */
529 bd0
= s2b(s0
, nd0
, nd
, y
);
538 bb
= d2b(dval(rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
558 #ifdef Honor_FLT_ROUNDS
562 #ifdef Avoid_Underflow
564 i
= j
+ bbbits
- 1; /* logb(rv) */
565 if (i
< Emin
) /* denormal */
569 #else /*Avoid_Underflow*/
570 #ifdef Sudden_Underflow
572 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
576 #else /*Sudden_Underflow*/
578 i
= j
+ bbbits
- 1; /* logb(rv) */
579 if (i
< Emin
) /* denormal */
583 #endif /*Sudden_Underflow*/
584 #endif /*Avoid_Underflow*/
587 #ifdef Avoid_Underflow
590 i
= bb2
< bd2
? bb2
: bd2
;
599 bs
= pow5mult(bs
, bb5
);
609 bb
= lshift(bb
, bb2
);
614 bd
= pow5mult(bd
, bd5
);
619 bd
= lshift(bd
, bd2
);
624 bs
= lshift(bs
, bs2
);
628 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
));
723 #endif /*Honor_FLT_ROUNDS*/
726 /* Error is less than half an ulp -- check for
727 * special case of mantissa a power of two.
729 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
731 #ifdef Avoid_Underflow
732 || (word0(rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
734 || (word0(rv
) & Exp_mask
) <= Exp_msk1
739 if (!delta
->x
[0] && delta
->wds
<= 1)
744 if (!delta
->x
[0] && delta
->wds
<= 1) {
751 delta
= lshift(delta
,Log2P
);
752 if (cmp(delta
, bs
) > 0)
757 /* exactly half-way between */
759 if ((word0(rv
) & Bndry_mask1
) == Bndry_mask1
761 #ifdef Avoid_Underflow
762 (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
763 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
766 /*boundary case -- increment exponent*/
767 word0(rv
) = (word0(rv
) & Exp_mask
)
774 #ifdef Avoid_Underflow
780 else if (!(word0(rv
) & Bndry_mask
) && !word1(rv
)) {
782 /* boundary case -- decrement exponent */
783 #ifdef Sudden_Underflow /*{{*/
784 L
= word0(rv
) & Exp_mask
;
788 #ifdef Avoid_Underflow
789 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
792 #endif /*Avoid_Underflow*/
796 #else /*Sudden_Underflow}{*/
797 #ifdef Avoid_Underflow
799 L
= word0(rv
) & Exp_mask
;
800 if (L
<= (2*P
+1)*Exp_msk1
) {
801 if (L
> (P
+2)*Exp_msk1
)
805 /* rv = smallest denormal */
809 #endif /*Avoid_Underflow*/
810 L
= (word0(rv
) & Exp_mask
) - Exp_msk1
;
811 #endif /*Sudden_Underflow}*/
812 word0(rv
) = (UINT32
)(L
| Bndry_mask1
);
813 word1(rv
) = 0xffffffffU
;
821 if (!(word1(rv
) & LSB
))
825 dval(rv
) += ulp(dval(rv
));
828 dval(rv
) -= ulp(dval(rv
));
829 #ifndef Sudden_Underflow
834 #ifdef Avoid_Underflow
840 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
843 else if (word1(rv
) || word0(rv
) & Bndry_mask
) {
844 #ifndef Sudden_Underflow
845 if (word1(rv
) == Tiny1
&& !word0(rv
))
852 /* special case -- power of FLT_RADIX to be */
853 /* rounded down... */
855 if (aadj
< 2./FLT_RADIX
)
864 aadj1
= dsign
? aadj
: -aadj
;
865 #ifdef Check_FLT_ROUNDS
867 case 2: /* towards +infinity */
870 case 0: /* towards 0 */
871 case 3: /* towards -infinity */
877 #endif /*Check_FLT_ROUNDS*/
879 y
= word0(rv
) & Exp_mask
;
881 /* Check for overflow */
883 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
884 dval(rv0
) = dval(rv
);
885 word0(rv
) -= P
*Exp_msk1
;
886 adj
= aadj1
* ulp(dval(rv
));
888 if ((word0(rv
) & Exp_mask
) >=
889 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
890 if (word0(rv0
) == Big0
&& word1(rv0
) == Big1
)
897 word0(rv
) += P
*Exp_msk1
;
900 #ifdef Avoid_Underflow
901 if (scale
&& y
<= 2*P
*Exp_msk1
) {
902 if (aadj
<= 0x7fffffff) {
903 if ((z
= (uint32_t)aadj
) == 0)
906 aadj1
= dsign
? aadj
: -aadj
;
908 word0(aadj1
) += (UINT32
)((2*P
+1)*Exp_msk1
- y
);
910 adj
= aadj1
* ulp(dval(rv
));
913 #ifdef Sudden_Underflow
914 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
915 dval(rv0
) = dval(rv
);
916 word0(rv
) += P
*Exp_msk1
;
917 adj
= aadj1
* ulp(dval(rv
));
920 if ((word0(rv
) & Exp_mask
) < P
*Exp_msk1
)
922 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
)
925 if (word0(rv0
) == Tiny0
926 && word1(rv0
) == Tiny1
)
933 word0(rv
) -= P
*Exp_msk1
;
936 adj
= aadj1
* ulp(dval(rv
));
939 #else /*Sudden_Underflow*/
940 /* Compute adj so that the IEEE rounding rules will
941 * correctly round rv + adj in some half-way cases.
942 * If rv * ulp(rv) is denormalized (i.e.,
943 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
944 * trouble from bits lost to denormalization;
945 * example: 1.2e-307 .
947 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
948 aadj1
= (double)(int)(aadj
+ 0.5);
952 adj
= aadj1
* ulp(dval(rv
));
954 #endif /*Sudden_Underflow*/
955 #endif /*Avoid_Underflow*/
957 z
= word0(rv
) & Exp_mask
;
959 #ifdef Avoid_Underflow
963 /* Can we stop now? */
966 /* The tolerances below are conservative. */
967 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
) {
968 if (aadj
< .4999999 || aadj
> .5000001)
971 else if (aadj
< .4999999/FLT_RADIX
)
984 word0(rv0
) = Exp_1
+ (70 << Exp_shift
);
989 else if (!oldinexact
)
992 #ifdef Avoid_Underflow
994 word0(rv0
) = Exp_1
- 2*P
*Exp_msk1
;
996 dval(rv
) *= dval(rv0
);
998 /* try to avoid the bug of testing an 8087 register value */
999 if (word0(rv
) == 0 && word1(rv
) == 0)
1003 #endif /* Avoid_Underflow */
1005 if (inexact
&& !(word0(rv
) & Exp_mask
)) {
1006 /* set underflow bit */
1008 dval(rv0
) *= dval(rv0
);
1020 return sign
? -dval(rv
) : dval(rv
);