Rev 4874 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4874 | Rev 4921 | ||
---|---|---|---|
Line 9... | Line 9... | ||
9 | INDEX |
9 | INDEX |
10 | strtof |
10 | strtof |
Line 11... | Line 11... | ||
11 | 11 | ||
12 | ANSI_SYNOPSIS |
12 | ANSI_SYNOPSIS |
13 | #include |
13 | #include |
14 | double strtod(const char *<[str]>, char **<[tail]>); |
14 | double strtod(const char *restrict <[str]>, char **restrict <[tail]>); |
Line 15... | Line 15... | ||
15 | float strtof(const char *<[str]>, char **<[tail]>); |
15 | float strtof(const char *restrict <[str]>, char **restrict <[tail]>); |
16 | 16 | ||
Line 17... | Line 17... | ||
17 | double _strtod_r(void *<[reent]>, |
17 | double _strtod_r(void *<[reent]>, |
18 | const char *<[str]>, char **<[tail]>); |
18 | const char *restrict <[str]>, char **restrict <[tail]>); |
19 | 19 | ||
20 | TRAD_SYNOPSIS |
20 | TRAD_SYNOPSIS |
Line 126... | Line 126... | ||
126 | 126 | ||
127 | #ifdef IEEE_Arith |
127 | #ifdef IEEE_Arith |
128 | #ifndef NO_IEEE_Scale |
128 | #ifndef NO_IEEE_Scale |
129 | #define Avoid_Underflow |
129 | #define Avoid_Underflow |
130 | #undef tinytens |
130 | #undef tinytens |
131 | /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ |
131 | /* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */ |
132 | /* flag unnecessarily. It leads to a song and dance at the end of strtod. */ |
132 | /* flag unnecessarily. It leads to a song and dance at the end of strtod. */ |
- | 133 | static _CONST double tinytens[] = { 1e-16, 1e-32, |
|
- | 134 | #ifdef _DOUBLE_IS_32BITS |
|
- | 135 | 0.0, 0.0, 0.0 |
|
- | 136 | #else |
|
133 | static _CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, |
137 | 1e-64, 1e-128, |
- | 138 | 9007199254740992. * 9007199254740992.e-256 |
|
134 | 9007199254740992.e-256 |
139 | #endif |
- | 140 | }; |
|
135 | }; |
141 | |
136 | #endif |
142 | #endif |
Line 137... | Line 143... | ||
137 | #endif |
143 | #endif |
138 | 144 | ||
Line 142... | Line 148... | ||
142 | #define Check_FLT_ROUNDS |
148 | #define Check_FLT_ROUNDS |
143 | #else |
149 | #else |
144 | #define Rounding Flt_Rounds |
150 | #define Rounding Flt_Rounds |
145 | #endif |
151 | #endif |
Line -... | Line 152... | ||
- | 152 | ||
- | 153 | #ifdef Avoid_Underflow /*{*/ |
|
- | 154 | static double |
|
- | 155 | _DEFUN (sulp, (x, scale), |
|
- | 156 | U x _AND |
|
- | 157 | int scale) |
|
- | 158 | { |
|
- | 159 | U u; |
|
- | 160 | double rv; |
|
- | 161 | int i; |
|
- | 162 | ||
- | 163 | rv = ulp(dval(x)); |
|
- | 164 | if (!scale || (i = 2*P + 1 - ((dword0(x) & Exp_mask) >> Exp_shift)) <= 0) |
|
- | 165 | return rv; /* Is there an example where i <= 0 ? */ |
|
- | 166 | dword0(u) = Exp_1 + (i << Exp_shift); |
|
- | 167 | #ifndef _DOUBLE_IS_32BITS |
|
- | 168 | dword1(u) = 0; |
|
- | 169 | #endif |
|
- | 170 | return rv * u.d; |
|
- | 171 | } |
|
- | 172 | #endif /*}*/ |
|
- | 173 | ||
146 | 174 | ||
Line 147... | Line 175... | ||
147 | #ifndef NO_HEX_FP |
175 | #ifndef NO_HEX_FP |
148 | 176 | ||
149 | static void |
177 | static void |
Line 206... | Line 234... | ||
206 | 234 | ||
207 | 235 | ||
208 | double |
236 | double |
209 | _DEFUN (_strtod_r, (ptr, s00, se), |
237 | _DEFUN (_strtod_r, (ptr, s00, se), |
210 | struct _reent *ptr _AND |
238 | struct _reent *ptr _AND |
211 | _CONST char *s00 _AND |
239 | _CONST char *__restrict s00 _AND |
212 | char **se) |
240 | char **__restrict se) |
213 | { |
241 | { |
214 | #ifdef Avoid_Underflow |
242 | #ifdef Avoid_Underflow |
215 | int scale; |
243 | int scale; |
Line 219... | Line 247... | ||
219 | _CONST char *s, *s0, *s1; |
247 | _CONST char *s, *s0, *s1; |
220 | double aadj, adj; |
248 | double aadj, adj; |
221 | U aadj1, rv, rv0; |
249 | U aadj1, rv, rv0; |
222 | Long L; |
250 | Long L; |
223 | __ULong y, z; |
251 | __ULong y, z; |
224 | _Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; |
252 | _Bigint *bb = NULL, *bb1, *bd = NULL, *bd0, *bs = NULL, *delta = NULL; |
- | 253 | #ifdef Avoid_Underflow |
|
- | 254 | __ULong Lsb, Lsb1; |
|
- | 255 | #endif |
|
225 | #ifdef SET_INEXACT |
256 | #ifdef SET_INEXACT |
226 | int inexact, oldinexact; |
257 | int inexact, oldinexact; |
227 | #endif |
258 | #endif |
228 | #ifdef Honor_FLT_ROUNDS |
259 | #ifdef Honor_FLT_ROUNDS |
229 | int rounding; |
260 | int rounding; |
Line 254... | Line 285... | ||
254 | } |
285 | } |
255 | break2: |
286 | break2: |
256 | if (*s == '0') { |
287 | if (*s == '0') { |
257 | #ifndef NO_HEX_FP |
288 | #ifndef NO_HEX_FP |
258 | { |
289 | { |
259 | static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; |
290 | static _CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; |
260 | Long exp; |
291 | Long exp; |
261 | __ULong bits[2]; |
292 | __ULong bits[2]; |
262 | switch(s[1]) { |
293 | switch(s[1]) { |
263 | case 'x': |
294 | case 'x': |
264 | case 'X': |
295 | case 'X': |
Line 277... | Line 308... | ||
277 | #define fpi1 fpi |
308 | #define fpi1 fpi |
278 | #endif |
309 | #endif |
279 | switch((i = gethex(ptr, &s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { |
310 | switch((i = gethex(ptr, &s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { |
280 | case STRTOG_NoNumber: |
311 | case STRTOG_NoNumber: |
281 | s = s00; |
312 | s = s00; |
- | 313 | sign = 0; |
|
- | 314 | /* FALLTHROUGH */ |
|
282 | case STRTOG_Zero: |
315 | case STRTOG_Zero: |
283 | break; |
316 | break; |
284 | default: |
317 | default: |
285 | if (bb) { |
318 | if (bb) { |
286 | copybits(bits, fpi.nbits, bb); |
319 | copybits(bits, fpi.nbits, bb); |
Line 297... | Line 330... | ||
297 | if (!*s) |
330 | if (!*s) |
298 | goto ret; |
331 | goto ret; |
299 | } |
332 | } |
300 | s0 = s; |
333 | s0 = s; |
301 | y = z = 0; |
334 | y = z = 0; |
302 | for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) { |
335 | for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) |
303 | if (nd < DBL_DIG + 1) { |
- | |
304 | if (nd < 9) |
336 | if (nd < 9) |
305 | y = 10*y + c - '0'; |
337 | y = 10*y + c - '0'; |
306 | else |
338 | else |
307 | z = 10*z + c - '0'; |
339 | z = 10*z + c - '0'; |
308 | } |
- | |
309 | } |
- | |
310 | nd0 = nd; |
340 | nd0 = nd; |
311 | if (strncmp (s, _localeconv_r (ptr)->decimal_point, |
341 | if (strncmp (s, _localeconv_r (ptr)->decimal_point, |
312 | strlen (_localeconv_r (ptr)->decimal_point)) == 0) { |
342 | strlen (_localeconv_r (ptr)->decimal_point)) == 0) |
- | 343 | { |
|
313 | decpt = 1; |
344 | decpt = 1; |
314 | c = *(s += strlen (_localeconv_r (ptr)->decimal_point)); |
345 | c = *(s += strlen (_localeconv_r (ptr)->decimal_point)); |
315 | if (!nd) { |
346 | if (!nd) { |
316 | for(; c == '0'; c = *++s) |
347 | for(; c == '0'; c = *++s) |
317 | nz++; |
348 | nz++; |
Line 325... | Line 356... | ||
325 | } |
356 | } |
326 | for(; c >= '0' && c <= '9'; c = *++s) { |
357 | for(; c >= '0' && c <= '9'; c = *++s) { |
327 | have_dig: |
358 | have_dig: |
328 | nz++; |
359 | nz++; |
329 | if (c -= '0') { |
360 | if (c -= '0') { |
330 | for(i = 1; i < nz; i++) { |
361 | nf += nz; |
331 | if (nd <= DBL_DIG + 1) { |
362 | for(i = 1; i < nz; i++) |
332 | if (nd + i < 10) |
363 | if (nd++ < 9) |
333 | y *= 10; |
364 | y *= 10; |
334 | else |
365 | else if (nd <= DBL_DIG + 1) |
335 | z *= 10; |
366 | z *= 10; |
336 | } |
- | |
337 | } |
- | |
338 | if (nd <= DBL_DIG + 1) { |
- | |
339 | if (nd + i < 10) |
367 | if (nd++ < 9) |
340 | y = 10*y + c; |
368 | y = 10*y + c; |
341 | else |
369 | else if (nd <= DBL_DIG + 1) |
342 | z = 10*z + c; |
370 | z = 10*z + c; |
343 | } |
- | |
344 | if (nd <= DBL_DIG + 1) { |
- | |
345 | nf += nz; |
- | |
346 | nd += nz; |
- | |
347 | } |
- | |
348 | nz = 0; |
371 | nz = 0; |
349 | } |
372 | } |
350 | } |
373 | } |
351 | } |
374 | } |
352 | dig_done: |
375 | dig_done: |
Line 390... | Line 413... | ||
390 | if (!nd) { |
413 | if (!nd) { |
391 | if (!nz && !nz0) { |
414 | if (!nz && !nz0) { |
392 | #ifdef INFNAN_CHECK |
415 | #ifdef INFNAN_CHECK |
393 | /* Check for Nan and Infinity */ |
416 | /* Check for Nan and Infinity */ |
394 | __ULong bits[2]; |
417 | __ULong bits[2]; |
395 | static FPI fpinan = /* only 52 explicit bits */ |
418 | static _CONST FPI fpinan = /* only 52 explicit bits */ |
396 | { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; |
419 | { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; |
397 | if (!decpt) |
420 | if (!decpt) |
398 | switch(c) { |
421 | switch(c) { |
399 | case 'i': |
422 | case 'i': |
400 | case 'I': |
423 | case 'I': |
Line 691... | Line 714... | ||
691 | /* Now the hard part -- adjusting rv to the correct value.*/ |
714 | /* Now the hard part -- adjusting rv to the correct value.*/ |
Line 692... | Line 715... | ||
692 | 715 | ||
Line 693... | Line 716... | ||
693 | /* Put digits into bd: true value = bd * 10^e */ |
716 | /* Put digits into bd: true value = bd * 10^e */ |
- | 717 | ||
- | 718 | bd0 = s2b(ptr, s0, nd0, nd, y); |
|
Line 694... | Line 719... | ||
694 | 719 | if (bd0 == NULL) |
|
695 | bd0 = s2b(ptr, s0, nd0, nd, y); |
720 | goto ovfl; |
- | 721 | ||
- | 722 | for(;;) { |
|
696 | 723 | bd = Balloc(ptr,bd0->_k); |
|
697 | for(;;) { |
724 | if (bd == NULL) |
- | 725 | goto ovfl; |
|
- | 726 | Bcopy(bd, bd0); |
|
698 | bd = Balloc(ptr,bd0->_k); |
727 | bb = d2b(ptr,dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ |
- | 728 | if (bb == NULL) |
|
- | 729 | goto ovfl; |
|
Line 699... | Line 730... | ||
699 | Bcopy(bd, bd0); |
730 | bs = i2b(ptr,1); |
700 | bb = d2b(ptr,dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ |
731 | if (bs == NULL) |
701 | bs = i2b(ptr,1); |
732 | goto ovfl; |
702 | 733 | ||
Line 716... | Line 747... | ||
716 | #ifdef Honor_FLT_ROUNDS |
747 | #ifdef Honor_FLT_ROUNDS |
717 | if (rounding != 1) |
748 | if (rounding != 1) |
718 | bs2++; |
749 | bs2++; |
719 | #endif |
750 | #endif |
720 | #ifdef Avoid_Underflow |
751 | #ifdef Avoid_Underflow |
- | 752 | Lsb = LSB; |
|
- | 753 | Lsb1 = 0; |
|
721 | j = bbe - scale; |
754 | j = bbe - scale; |
722 | i = j + bbbits - 1; /* logb(rv) */ |
755 | i = j + bbbits - 1; /* logb(rv) */ |
723 | if (i < Emin) /* denormal */ |
- | |
724 | j += P - Emin; |
- | |
725 | else |
- | |
726 | j = P + 1 - bbbits; |
756 | j = P + 1 - bbbits; |
- | 757 | if (i < Emin) { /* denormal */ |
|
- | 758 | i = Emin - i; |
|
- | 759 | j -= i; |
|
- | 760 | if (i < 32) |
|
- | 761 | Lsb <<= i; |
|
- | 762 | else |
|
- | 763 | Lsb1 = Lsb << (i-32); |
|
- | 764 | } |
|
727 | #else /*Avoid_Underflow*/ |
765 | #else /*Avoid_Underflow*/ |
728 | #ifdef Sudden_Underflow |
766 | #ifdef Sudden_Underflow |
729 | #ifdef IBM |
767 | #ifdef IBM |
730 | j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); |
768 | j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); |
731 | #else |
769 | #else |
Line 753... | Line 791... | ||
753 | bd2 -= i; |
791 | bd2 -= i; |
754 | bs2 -= i; |
792 | bs2 -= i; |
755 | } |
793 | } |
756 | if (bb5 > 0) { |
794 | if (bb5 > 0) { |
757 | bs = pow5mult(ptr, bs, bb5); |
795 | bs = pow5mult(ptr, bs, bb5); |
- | 796 | if (bs == NULL) |
|
- | 797 | goto ovfl; |
|
758 | bb1 = mult(ptr, bs, bb); |
798 | bb1 = mult(ptr, bs, bb); |
- | 799 | if (bb1 == NULL) |
|
- | 800 | goto ovfl; |
|
759 | Bfree(ptr, bb); |
801 | Bfree(ptr, bb); |
760 | bb = bb1; |
802 | bb = bb1; |
761 | } |
803 | } |
762 | if (bb2 > 0) |
804 | if (bb2 > 0) { |
763 | bb = lshift(ptr, bb, bb2); |
805 | bb = lshift(ptr, bb, bb2); |
- | 806 | if (bb == NULL) |
|
- | 807 | goto ovfl; |
|
- | 808 | } |
|
764 | if (bd5 > 0) |
809 | if (bd5 > 0) { |
765 | bd = pow5mult(ptr, bd, bd5); |
810 | bd = pow5mult(ptr, bd, bd5); |
- | 811 | if (bd == NULL) |
|
- | 812 | goto ovfl; |
|
- | 813 | } |
|
766 | if (bd2 > 0) |
814 | if (bd2 > 0) { |
767 | bd = lshift(ptr, bd, bd2); |
815 | bd = lshift(ptr, bd, bd2); |
- | 816 | if (bd == NULL) |
|
- | 817 | goto ovfl; |
|
- | 818 | } |
|
768 | if (bs2 > 0) |
819 | if (bs2 > 0) { |
769 | bs = lshift(ptr, bs, bs2); |
820 | bs = lshift(ptr, bs, bs2); |
- | 821 | if (bs == NULL) |
|
- | 822 | goto ovfl; |
|
- | 823 | } |
|
770 | delta = diff(ptr, bb, bd); |
824 | delta = diff(ptr, bb, bd); |
- | 825 | if (delta == NULL) |
|
- | 826 | goto ovfl; |
|
771 | dsign = delta->_sign; |
827 | dsign = delta->_sign; |
772 | delta->_sign = 0; |
828 | delta->_sign = 0; |
773 | i = cmp(delta, bs); |
829 | i = cmp(delta, bs); |
774 | #ifdef Honor_FLT_ROUNDS |
830 | #ifdef Honor_FLT_ROUNDS |
775 | if (rounding != 1) { |
831 | if (rounding != 1) { |
Line 852... | Line 908... | ||
852 | goto cont; |
908 | goto cont; |
853 | } |
909 | } |
854 | #endif /*Sudden_Underflow*/ |
910 | #endif /*Sudden_Underflow*/ |
855 | #endif /*Avoid_Underflow*/ |
911 | #endif /*Avoid_Underflow*/ |
856 | adj *= ulp(dval(rv)); |
912 | adj *= ulp(dval(rv)); |
857 | if (dsign) |
913 | if (dsign) { |
- | 914 | if (dword0(rv) == Big0 && dword1(rv) == Big1) |
|
- | 915 | goto ovfl; |
|
858 | dval(rv) += adj; |
916 | dval(rv) += adj; |
859 | else |
917 | else |
860 | dval(rv) -= adj; |
918 | dval(rv) -= adj; |
861 | goto cont; |
919 | goto cont; |
862 | } |
920 | } |
Line 902... | Line 960... | ||
902 | (scale && (y = dword0(rv) & Exp_mask) <= 2*P*Exp_msk1) |
960 | (scale && (y = dword0(rv) & Exp_mask) <= 2*P*Exp_msk1) |
903 | ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : |
961 | ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : |
904 | #endif |
962 | #endif |
905 | 0xffffffff)) { |
963 | 0xffffffff)) { |
906 | /*boundary case -- increment exponent*/ |
964 | /*boundary case -- increment exponent*/ |
- | 965 | if (dword0(rv) == Big0 && dword1(rv) == Big1) |
|
- | 966 | goto ovfl; |
|
907 | dword0(rv) = (dword0(rv) & Exp_mask) |
967 | dword0(rv) = (dword0(rv) & Exp_mask) |
908 | + Exp_msk1 |
968 | + Exp_msk1 |
909 | #ifdef IBM |
969 | #ifdef IBM |
910 | | Exp_msk1 >> 4 |
970 | | Exp_msk1 >> 4 |
911 | #endif |
971 | #endif |
Line 960... | Line 1020... | ||
960 | #else |
1020 | #else |
961 | break; |
1021 | break; |
962 | #endif |
1022 | #endif |
963 | } |
1023 | } |
964 | #ifndef ROUND_BIASED |
1024 | #ifndef ROUND_BIASED |
- | 1025 | #ifdef Avoid_Underflow |
|
- | 1026 | if (Lsb1) { |
|
- | 1027 | if (!(dword0(rv) & Lsb1)) |
|
- | 1028 | break; |
|
- | 1029 | } |
|
- | 1030 | else if (!(dword1(rv) & Lsb)) |
|
- | 1031 | break; |
|
- | 1032 | #else |
|
965 | if (!(dword1(rv) & LSB)) |
1033 | if (!(dword1(rv) & LSB)) |
966 | break; |
1034 | break; |
967 | #endif |
1035 | #endif |
- | 1036 | #endif |
|
968 | if (dsign) |
1037 | if (dsign) |
- | 1038 | #ifdef Avoid_Underflow |
|
- | 1039 | dval(rv) += sulp(rv, scale); |
|
- | 1040 | #else |
|
969 | dval(rv) += ulp(dval(rv)); |
1041 | dval(rv) += ulp(dval(rv)); |
- | 1042 | #endif |
|
970 | #ifndef ROUND_BIASED |
1043 | #ifndef ROUND_BIASED |
971 | else { |
1044 | else { |
- | 1045 | #ifdef Avoid_Underflow |
|
- | 1046 | dval(rv) -= sulp(rv, scale); |
|
- | 1047 | #else |
|
972 | dval(rv) -= ulp(dval(rv)); |
1048 | dval(rv) -= ulp(dval(rv)); |
- | 1049 | #endif |
|
973 | #ifndef Sudden_Underflow |
1050 | #ifndef Sudden_Underflow |
974 | if (!dval(rv)) |
1051 | if (!dval(rv)) |
975 | goto undfl; |
1052 | goto undfl; |
976 | #endif |
1053 | #endif |
977 | } |
1054 | } |
Line 1044... | Line 1121... | ||
1044 | } |
1121 | } |
1045 | else { |
1122 | else { |
1046 | #ifdef Avoid_Underflow |
1123 | #ifdef Avoid_Underflow |
1047 | if (scale && y <= 2*P*Exp_msk1) { |
1124 | if (scale && y <= 2*P*Exp_msk1) { |
1048 | if (aadj <= 0x7fffffff) { |
1125 | if (aadj <= 0x7fffffff) { |
1049 | if ((z = aadj) <= 0) |
1126 | if ((z = aadj) == 0) |
1050 | z = 1; |
1127 | z = 1; |
1051 | aadj = z; |
1128 | aadj = z; |
1052 | dval(aadj1) = dsign ? aadj : -aadj; |
1129 | dval(aadj1) = dsign ? aadj : -aadj; |
1053 | } |
1130 | } |
1054 | dword0(aadj1) += (2*P+1)*Exp_msk1 - y; |
1131 | dword0(aadj1) += (2*P+1)*Exp_msk1 - y; |
Line 1176... | Line 1253... | ||
1176 | 1253 | ||
Line 1177... | Line 1254... | ||
1177 | #ifndef _REENT_ONLY |
1254 | #ifndef _REENT_ONLY |
1178 | 1255 | ||
1179 | double |
1256 | double |
1180 | _DEFUN (strtod, (s00, se), |
1257 | _DEFUN (strtod, (s00, se), |
1181 | _CONST char *s00 _AND char **se) |
1258 | _CONST char *__restrict s00 _AND char **__restrict se) |
1182 | { |
1259 | { |
Line 1183... | Line 1260... | ||
1183 | return _strtod_r (_REENT, s00, se); |
1260 | return _strtod_r (_REENT, s00, se); |
1184 | } |
1261 | } |
1185 | 1262 | ||
1186 | float |
1263 | float |
1187 | _DEFUN (strtof, (s00, se), |
1264 | _DEFUN (strtof, (s00, se), |
1188 | _CONST char *s00 _AND |
1265 | _CONST char *__restrict s00 _AND |
1189 | char **se) |
1266 | char **__restrict se) |
1190 | { |
1267 | { |
1191 | double retval = _strtod_r (_REENT, s00, se); |
1268 | double retval = _strtod_r (_REENT, s00, se); |