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 "."). */
43 #define Avoid_Underflow
45 /* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */
46 /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
47 static CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128,
48 9007199254740992.*9007199254740992.e
-256
53 #ifdef Honor_FLT_ROUNDS
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
, decpt
, 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 USE_LOCALE /*{{*/
82 #ifdef NO_LOCALE_CACHE
83 char *decimalpoint
= localeconv()->decimal_point
;
84 int dplen
= strlen(decimalpoint
);
87 static char *decimalpoint_cache
;
89 if (!(s0
= decimalpoint_cache
)) {
90 s0
= localeconv()->decimal_point
;
91 if ((decimalpoint_cache
= (char*)malloc(strlen(s0
) + 1))) {
92 strcpy(decimalpoint_cache
, s0
);
93 s0
= decimalpoint_cache
;
97 decimalpoint
= (char*)s0
;
98 #endif /*NO_LOCALE_CACHE*/
99 #else /*USE_LOCALE}{*/
101 #endif /*USE_LOCALE}}*/
103 #ifdef Honor_FLT_ROUNDS /*{*/
105 #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
106 Rounding
= Flt_Rounds
;
109 switch(fegetround()) {
110 case FE_TOWARDZERO
: Rounding
= 0; break;
111 case FE_UPWARD
: Rounding
= 2; break;
112 case FE_DOWNWARD
: Rounding
= 3;
117 sign
= nz0
= nz
= decpt
= 0;
119 for(s
= s00
;;s
++) switch(*s
) {
141 #ifndef NO_HEX_FP /*{*/
143 static FPI fpi
= { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
150 #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) /*{{*/
152 #ifdef Honor_FLT_ROUNDS /*{{*/
153 fpi1
.rounding
= Rounding
;
155 switch(fegetround()) {
156 case FE_TOWARDZERO
: fpi1
.rounding
= 0; break;
157 case FE_UPWARD
: fpi1
.rounding
= 2; break;
158 case FE_DOWNWARD
: fpi1
.rounding
= 3;
164 switch((i
= gethex(&s
, &fpi1
, &exp
, &bb
, sign
)) & STRTOG_Retmask
) {
165 case STRTOG_NoNumber
:
172 copybits(bits
, fpi
.nbits
, bb
);
175 ULtod(((U
*)&rv
)->L
, bits
, exp
, i
);
188 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
195 if (c
== *decimalpoint
) {
196 for(i
= 1; decimalpoint
[i
]; ++i
)
197 if (s
[i
] != decimalpoint
[i
])
207 for(; c
== '0'; c
= *++s
)
209 if (c
> '0' && c
<= '9') {
217 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
222 for(i
= 1; i
< nz
; i
++)
225 else if (nd
<= DBL_DIG
+ 1)
229 else if (nd
<= DBL_DIG
+ 1)
237 if (c
== 'e' || c
== 'E') {
238 if (!nd
&& !nz
&& !nz0
) {
249 if (c
>= '0' && c
<= '9') {
252 if (c
> '0' && c
<= '9') {
255 while((c
= *++s
) >= '0' && c
<= '9')
257 if (s
- s1
> 8 || L
> 19999)
258 /* Avoid confusion from exponents
259 * so large that e might overflow.
261 e
= 19999; /* safe for 16 bit ints */
276 /* Check for Nan and Infinity */
278 static FPI fpinan
= /* only 52 explicit bits */
279 { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI
};
284 if (match(&s
,"nf")) {
286 if (!match(&s
,"inity"))
288 word0(rv
) = 0x7ff00000;
295 if (match(&s
, "an")) {
298 && hexnan(&s
, &fpinan
, bits
)
300 word0(rv
) = 0x7ff00000 | bits
[1];
305 word0(rv
) = NAN_WORD0
;
306 word1(rv
) = NAN_WORD1
;
313 #endif /* INFNAN_CHECK */
322 /* Now we have nd0 digits, starting at s0, followed by a
323 * decimal point, followed by nd-nd0 digits. The number we're
324 * after is the integer represented by those digits times
329 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
334 oldinexact
= get_inexact();
336 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
341 #ifndef Honor_FLT_ROUNDS
353 #ifdef Honor_FLT_ROUNDS
354 /* round correctly FLT_ROUNDS = 2 or 3 */
360 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
365 if (e
<= Ten_pmax
+ i
) {
366 /* A fancier test would sometimes let us do
367 * this for larger i values.
369 #ifdef Honor_FLT_ROUNDS
370 /* round correctly FLT_ROUNDS = 2 or 3 */
379 /* VAX exponent range is so narrow we must
380 * worry about overflow here...
383 word0(rv
) -= P
*Exp_msk1
;
384 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
385 if ((word0(rv
) & Exp_mask
)
386 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
388 word0(rv
) += P
*Exp_msk1
;
390 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
395 #ifndef Inaccurate_Divide
396 else if (e
>= -Ten_pmax
) {
397 #ifdef Honor_FLT_ROUNDS
398 /* round correctly FLT_ROUNDS = 2 or 3 */
404 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
415 oldinexact
= get_inexact();
417 #ifdef Avoid_Underflow
420 #ifdef Honor_FLT_ROUNDS
423 Rounding
= Rounding
== 2 ? 0 : 2;
429 #endif /*IEEE_Arith*/
431 /* Get starting approximation = rv * 10**e1 */
434 if ( (i
= e1
& 15) !=0)
437 if (e1
> DBL_MAX_10_EXP
) {
442 /* Can't trust HUGE_VAL */
444 #ifdef Honor_FLT_ROUNDS
446 case 0: /* toward 0 */
447 case 3: /* toward -infinity */
452 word0(rv
) = Exp_mask
;
455 #else /*Honor_FLT_ROUNDS*/
456 word0(rv
) = Exp_mask
;
458 #endif /*Honor_FLT_ROUNDS*/
460 /* set overflow bit */
462 dval(rv0
) *= dval(rv0
);
467 #endif /*IEEE_Arith*/
473 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
475 dval(rv
) *= bigtens
[j
];
476 /* The last multiplication could overflow. */
477 word0(rv
) -= P
*Exp_msk1
;
478 dval(rv
) *= bigtens
[j
];
479 if ((z
= word0(rv
) & Exp_mask
)
480 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
))
482 if (z
> Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
)) {
483 /* set to largest number */
484 /* (Can't trust DBL_MAX) */
489 word0(rv
) += P
*Exp_msk1
;
494 if ( (i
= e1
& 15) !=0)
497 if (e1
>= 1 << n_bigtens
)
499 #ifdef Avoid_Underflow
502 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
504 dval(rv
) *= tinytens
[j
];
505 if (scale
&& (j
= 2*P
+ 1 - ((word0(rv
) & Exp_mask
)
506 >> Exp_shift
)) > 0) {
507 /* scaled rv is denormal; zap j low bits */
511 word0(rv
) = (P
+2)*Exp_msk1
;
513 word0(rv
) &= 0xffffffff << j
-32;
516 word1(rv
) &= 0xffffffff << j
;
519 for(j
= 0; e1
> 1; j
++, e1
>>= 1)
521 dval(rv
) *= tinytens
[j
];
522 /* The last multiplication could underflow. */
523 dval(rv0
) = dval(rv
);
524 dval(rv
) *= tinytens
[j
];
526 dval(rv
) = 2.*dval(rv0
);
527 dval(rv
) *= tinytens
[j
];
539 #ifndef Avoid_Underflow
542 /* The refinement below will clean
543 * this approximation up.
550 /* Now the hard part -- adjusting rv to the correct value.*/
552 /* Put digits into bd: true value = bd * 10^e */
554 bd0
= s2b(s0
, nd0
, nd
, y
, dplen
);
559 bb
= d2b(dval(rv
), &bbe
, &bbbits
); /* rv = bb * 2^bbe */
575 #ifdef Honor_FLT_ROUNDS
579 #ifdef Avoid_Underflow
581 i
= j
+ bbbits
- 1; /* logb(rv) */
582 if (i
< Emin
) /* denormal */
586 #else /*Avoid_Underflow*/
587 #ifdef Sudden_Underflow
589 j
= 1 + 4*P
- 3 - bbbits
+ ((bbe
+ bbbits
- 1) & 3);
593 #else /*Sudden_Underflow*/
595 i
= j
+ bbbits
- 1; /* logb(rv) */
596 if (i
< Emin
) /* denormal */
600 #endif /*Sudden_Underflow*/
601 #endif /*Avoid_Underflow*/
604 #ifdef Avoid_Underflow
607 i
= bb2
< bd2
? bb2
: bd2
;
616 bs
= pow5mult(bs
, bb5
);
622 bb
= lshift(bb
, bb2
);
624 bd
= pow5mult(bd
, bd5
);
626 bd
= lshift(bd
, bd2
);
628 bs
= lshift(bs
, bs2
);
629 delta
= diff(bb
, bd
);
633 #ifdef Honor_FLT_ROUNDS
636 /* Error is less than an ulp */
637 if (!delta
->x
[0] && delta
->wds
<= 1) {
653 && !(word0(rv
) & Frac_mask
)) {
654 y
= word0(rv
) & Exp_mask
;
655 #ifdef Avoid_Underflow
656 if (!scale
|| y
> 2*P
*Exp_msk1
)
661 delta
= lshift(delta
,Log2P
);
662 if (cmp(delta
, bs
) <= 0)
667 #ifdef Avoid_Underflow
668 if (scale
&& (y
= word0(rv
) & Exp_mask
)
670 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
672 #ifdef Sudden_Underflow
673 if ((word0(rv
) & Exp_mask
) <=
675 word0(rv
) += P
*Exp_msk1
;
676 dval(rv
) += adj
*ulp(dval(rv
));
677 word0(rv
) -= P
*Exp_msk1
;
680 #endif /*Sudden_Underflow*/
681 #endif /*Avoid_Underflow*/
682 dval(rv
) += adj
*ulp(dval(rv
));
686 adj
= ratio(delta
, bs
);
689 if (adj
<= 0x7ffffffe) {
690 /* adj = Rounding ? ceil(adj) : floor(adj); */
693 if (!((Rounding
>>1) ^ dsign
))
698 #ifdef Avoid_Underflow
699 if (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
700 word0(adj
) += (2*P
+1)*Exp_msk1
- y
;
702 #ifdef Sudden_Underflow
703 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
704 word0(rv
) += P
*Exp_msk1
;
705 adj
*= ulp(dval(rv
));
710 word0(rv
) -= P
*Exp_msk1
;
713 #endif /*Sudden_Underflow*/
714 #endif /*Avoid_Underflow*/
715 adj
*= ulp(dval(rv
));
717 if (word0(rv
) == Big0
&& word1(rv
) == Big1
)
725 #endif /*Honor_FLT_ROUNDS*/
728 /* Error is less than half an ulp -- check for
729 * special case of mantissa a power of two.
731 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
733 #ifdef Avoid_Underflow
734 || (word0(rv
) & Exp_mask
) <= (2*P
+1)*Exp_msk1
736 || (word0(rv
) & Exp_mask
) <= Exp_msk1
741 if (!delta
->x
[0] && delta
->wds
<= 1)
746 if (!delta
->x
[0] && delta
->wds
<= 1) {
753 delta
= lshift(delta
,Log2P
);
754 if (cmp(delta
, bs
) > 0)
759 /* exactly half-way between */
761 if ((word0(rv
) & Bndry_mask1
) == Bndry_mask1
763 #ifdef Avoid_Underflow
764 (scale
&& (y
= word0(rv
) & Exp_mask
) <= 2*P
*Exp_msk1
)
765 ? (0xffffffff & (0xffffffff << (2*P
+1-(y
>>Exp_shift
)))) :
768 /*boundary case -- increment exponent*/
769 word0(rv
) = (word0(rv
) & Exp_mask
)
776 #ifdef Avoid_Underflow
782 else if (!(word0(rv
) & Bndry_mask
) && !word1(rv
)) {
784 /* boundary case -- decrement exponent */
785 #ifdef Sudden_Underflow /*{{*/
786 L
= word0(rv
) & Exp_mask
;
790 #ifdef Avoid_Underflow
791 if (L
<= (scale
? (2*P
+1)*Exp_msk1
: Exp_msk1
))
794 #endif /*Avoid_Underflow*/
798 #else /*Sudden_Underflow}{*/
799 #ifdef Avoid_Underflow
801 L
= word0(rv
) & Exp_mask
;
802 if (L
<= (2*P
+1)*Exp_msk1
) {
803 if (L
> (P
+2)*Exp_msk1
)
807 /* rv = smallest denormal */
811 #endif /*Avoid_Underflow*/
812 L
= (word0(rv
) & Exp_mask
) - Exp_msk1
;
813 #endif /*Sudden_Underflow}}*/
814 word0(rv
) = L
| Bndry_mask1
;
815 word1(rv
) = 0xffffffff;
823 if (!(word1(rv
) & LSB
))
827 dval(rv
) += ulp(dval(rv
));
830 dval(rv
) -= ulp(dval(rv
));
831 #ifndef Sudden_Underflow
836 #ifdef Avoid_Underflow
842 if ((aadj
= ratio(delta
, bs
)) <= 2.) {
845 else if (word1(rv
) || word0(rv
) & Bndry_mask
) {
846 #ifndef Sudden_Underflow
847 if (word1(rv
) == Tiny1
&& !word0(rv
))
854 /* special case -- power of FLT_RADIX to be */
855 /* rounded down... */
857 if (aadj
< 2./FLT_RADIX
)
866 aadj1
= dsign
? aadj
: -aadj
;
867 #ifdef Check_FLT_ROUNDS
869 case 2: /* towards +infinity */
872 case 0: /* towards 0 */
873 case 3: /* towards -infinity */
879 #endif /*Check_FLT_ROUNDS*/
881 y
= word0(rv
) & Exp_mask
;
883 /* Check for overflow */
885 if (y
== Exp_msk1
*(DBL_MAX_EXP
+Bias
-1)) {
886 dval(rv0
) = dval(rv
);
887 word0(rv
) -= P
*Exp_msk1
;
888 adj
= aadj1
* ulp(dval(rv
));
890 if ((word0(rv
) & Exp_mask
) >=
891 Exp_msk1
*(DBL_MAX_EXP
+Bias
-P
)) {
892 if (word0(rv0
) == Big0
&& word1(rv0
) == Big1
)
899 word0(rv
) += P
*Exp_msk1
;
902 #ifdef Avoid_Underflow
903 if (scale
&& y
<= 2*P
*Exp_msk1
) {
904 if (aadj
<= 0x7fffffff) {
908 aadj1
= dsign
? aadj
: -aadj
;
910 word0(aadj1
) += (2*P
+1)*Exp_msk1
- y
;
912 adj
= aadj1
* ulp(dval(rv
));
915 #ifdef Sudden_Underflow
916 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
) {
917 dval(rv0
) = dval(rv
);
918 word0(rv
) += P
*Exp_msk1
;
919 adj
= aadj1
* ulp(dval(rv
));
922 if ((word0(rv
) & Exp_mask
) < P
*Exp_msk1
)
924 if ((word0(rv
) & Exp_mask
) <= P
*Exp_msk1
)
927 if (word0(rv0
) == Tiny0
928 && word1(rv0
) == Tiny1
)
935 word0(rv
) -= P
*Exp_msk1
;
938 adj
= aadj1
* ulp(dval(rv
));
941 #else /*Sudden_Underflow*/
942 /* Compute adj so that the IEEE rounding rules will
943 * correctly round rv + adj in some half-way cases.
944 * If rv * ulp(rv) is denormalized (i.e.,
945 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
946 * trouble from bits lost to denormalization;
947 * example: 1.2e-307 .
949 if (y
<= (P
-1)*Exp_msk1
&& aadj
> 1.) {
950 aadj1
= (double)(int)(aadj
+ 0.5);
954 adj
= aadj1
* ulp(dval(rv
));
956 #endif /*Sudden_Underflow*/
957 #endif /*Avoid_Underflow*/
959 z
= word0(rv
) & Exp_mask
;
961 #ifdef Avoid_Underflow
965 /* Can we stop now? */
968 /* The tolerances below are conservative. */
969 if (dsign
|| word1(rv
) || word0(rv
) & Bndry_mask
) {
970 if (aadj
< .4999999 || aadj
> .5000001)
973 else if (aadj
< .4999999/FLT_RADIX
)
986 word0(rv0
) = Exp_1
+ (70 << Exp_shift
);
991 else if (!oldinexact
)
994 #ifdef Avoid_Underflow
996 word0(rv0
) = Exp_1
- 2*P
*Exp_msk1
;
998 dval(rv
) *= dval(rv0
);
1000 /* try to avoid the bug of testing an 8087 register value */
1002 if (!(word0(rv
) & Exp_mask
))
1004 if (word0(rv
) == 0 && word1(rv
) == 0)
1009 #endif /* Avoid_Underflow */
1011 if (inexact
&& !(word0(rv
) & Exp_mask
)) {
1012 /* set underflow bit */
1014 dval(rv0
) *= dval(rv0
);
1026 return sign
? -dval(rv
) : dval(rv
);