]>
Commit | Line | Data |
---|---|---|
9385eb3d A |
1 | /**************************************************************** |
2 | ||
3 | The author of this software is David M. Gay. | |
4 | ||
5 | Copyright (C) 1998-2001 by Lucent Technologies | |
6 | All Rights Reserved | |
7 | ||
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 | |
16 | permission. | |
17 | ||
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 | |
25 | THIS SOFTWARE. | |
26 | ||
27 | ****************************************************************/ | |
28 | ||
3d9156a7 A |
29 | /* Please send bug reports to David M. Gay (dmg at acm dot org, |
30 | * with " at " changed at "@" and " dot " changed to "."). */ | |
9385eb3d | 31 | |
ad3c9f2a A |
32 | #include "xlocale_private.h" |
33 | ||
9385eb3d | 34 | #include "gdtoaimp.h" |
eb1cde05 A |
35 | #ifndef NO_FENV_H |
36 | #include <fenv.h> | |
37 | #endif | |
9385eb3d A |
38 | |
39 | #ifdef USE_LOCALE | |
40 | #include "locale.h" | |
41 | #endif | |
42 | ||
43 | #ifdef IEEE_Arith | |
44 | #ifndef NO_IEEE_Scale | |
45 | #define Avoid_Underflow | |
46 | #undef tinytens | |
34e8f829 | 47 | /* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */ |
9385eb3d A |
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, | |
34e8f829 | 50 | 9007199254740992.*9007199254740992.e-256 |
9385eb3d A |
51 | }; |
52 | #endif | |
53 | #endif | |
54 | ||
55 | #ifdef Honor_FLT_ROUNDS | |
9385eb3d A |
56 | #undef Check_FLT_ROUNDS |
57 | #define Check_FLT_ROUNDS | |
58 | #else | |
59 | #define Rounding Flt_Rounds | |
60 | #endif | |
61 | ||
62 | double | |
ad3c9f2a | 63 | strtod_l |
9385eb3d | 64 | #ifdef KR_headers |
ad3c9f2a | 65 | (s00, se, loc) CONST char *s00; char **se; locale_t loc; |
9385eb3d | 66 | #else |
ad3c9f2a | 67 | (CONST char *s00, char **se, locale_t loc) |
9385eb3d A |
68 | #endif |
69 | { | |
70 | #ifdef Avoid_Underflow | |
71 | int scale; | |
72 | #endif | |
3d9156a7 | 73 | int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, |
9385eb3d A |
74 | e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; |
75 | CONST char *s, *s0, *s1; | |
ad3c9f2a | 76 | char *strunc = NULL; |
1f2f436a | 77 | double aadj; |
9385eb3d | 78 | Long L; |
1f2f436a | 79 | U adj, aadj1, rv, rv0; |
9385eb3d A |
80 | ULong y, z; |
81 | Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; | |
82 | #ifdef SET_INEXACT | |
83 | int inexact, oldinexact; | |
84 | #endif | |
1f2f436a | 85 | #ifdef USE_LOCALE /*{{*/ |
ad3c9f2a | 86 | NORMALIZE_LOCALE(loc); |
34e8f829 | 87 | #ifdef NO_LOCALE_CACHE |
ad3c9f2a | 88 | char *decimalpoint = localeconv_l(loc)->decimal_point; |
1f2f436a | 89 | int dplen = strlen(decimalpoint); |
34e8f829 A |
90 | #else |
91 | char *decimalpoint; | |
92 | static char *decimalpoint_cache; | |
1f2f436a | 93 | static int dplen; |
34e8f829 | 94 | if (!(s0 = decimalpoint_cache)) { |
ad3c9f2a | 95 | s0 = localeconv_l(loc)->decimal_point; |
1f2f436a | 96 | if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { |
34e8f829 A |
97 | strcpy(decimalpoint_cache, s0); |
98 | s0 = decimalpoint_cache; | |
99 | } | |
1f2f436a | 100 | dplen = strlen(s0); |
34e8f829 A |
101 | } |
102 | decimalpoint = (char*)s0; | |
1f2f436a A |
103 | #endif /*NO_LOCALE_CACHE*/ |
104 | #else /*USE_LOCALE}{*/ | |
105 | #define dplen 1 | |
106 | #endif /*USE_LOCALE}}*/ | |
107 | ||
34e8f829 A |
108 | #ifdef Honor_FLT_ROUNDS /*{*/ |
109 | int Rounding; | |
110 | #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ | |
111 | Rounding = Flt_Rounds; | |
112 | #else /*}{*/ | |
113 | Rounding = 1; | |
114 | switch(fegetround()) { | |
115 | case FE_TOWARDZERO: Rounding = 0; break; | |
116 | case FE_UPWARD: Rounding = 2; break; | |
117 | case FE_DOWNWARD: Rounding = 3; | |
118 | } | |
119 | #endif /*}}*/ | |
120 | #endif /*}*/ | |
9385eb3d | 121 | |
3d9156a7 | 122 | sign = nz0 = nz = decpt = 0; |
1f2f436a | 123 | dval(&rv) = 0.; |
9385eb3d A |
124 | for(s = s00;;s++) switch(*s) { |
125 | case '-': | |
126 | sign = 1; | |
127 | /* no break */ | |
128 | case '+': | |
129 | if (*++s) | |
130 | goto break2; | |
131 | /* no break */ | |
132 | case 0: | |
133 | goto ret0; | |
134 | case '\t': | |
135 | case '\n': | |
136 | case '\v': | |
137 | case '\f': | |
138 | case '\r': | |
139 | case ' ': | |
140 | continue; | |
141 | default: | |
142 | goto break2; | |
143 | } | |
144 | break2: | |
145 | if (*s == '0') { | |
34e8f829 | 146 | #ifndef NO_HEX_FP /*{*/ |
9385eb3d | 147 | { |
6465356a | 148 | static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; |
9385eb3d A |
149 | Long exp; |
150 | ULong bits[2]; | |
151 | switch(s[1]) { | |
152 | case 'x': | |
153 | case 'X': | |
eb1cde05 | 154 | { |
1f2f436a | 155 | #ifdef Honor_FLT_ROUNDS |
eb1cde05 | 156 | FPI fpi1 = fpi; |
34e8f829 | 157 | fpi1.rounding = Rounding; |
1f2f436a | 158 | #else |
eb1cde05 | 159 | #define fpi1 fpi |
1f2f436a | 160 | #endif |
ad3c9f2a | 161 | switch((i = gethex(&s, &fpi1, &exp, &bb, sign, loc)) & STRTOG_Retmask) { |
9385eb3d A |
162 | case STRTOG_NoNumber: |
163 | s = s00; | |
164 | sign = 0; | |
165 | case STRTOG_Zero: | |
166 | break; | |
167 | default: | |
59e0d9fe A |
168 | if (bb) { |
169 | copybits(bits, fpi.nbits, bb); | |
170 | Bfree(bb); | |
171 | } | |
9385eb3d | 172 | ULtod(((U*)&rv)->L, bits, exp, i); |
eb1cde05 | 173 | }} |
9385eb3d A |
174 | goto ret; |
175 | } | |
176 | } | |
34e8f829 | 177 | #endif /*}*/ |
9385eb3d A |
178 | nz0 = 1; |
179 | while(*++s == '0') ; | |
180 | if (!*s) | |
181 | goto ret; | |
182 | } | |
183 | s0 = s; | |
184 | y = z = 0; | |
185 | for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) | |
186 | if (nd < 9) | |
187 | y = 10*y + c - '0'; | |
188 | else if (nd < 16) | |
189 | z = 10*z + c - '0'; | |
190 | nd0 = nd; | |
191 | #ifdef USE_LOCALE | |
34e8f829 A |
192 | if (c == *decimalpoint) { |
193 | for(i = 1; decimalpoint[i]; ++i) | |
194 | if (s[i] != decimalpoint[i]) | |
195 | goto dig_done; | |
196 | s += i; | |
197 | c = *s; | |
9385eb3d | 198 | #else |
34e8f829 A |
199 | if (c == '.') { |
200 | c = *++s; | |
9385eb3d | 201 | #endif |
3d9156a7 | 202 | decpt = 1; |
9385eb3d A |
203 | if (!nd) { |
204 | for(; c == '0'; c = *++s) | |
205 | nz++; | |
206 | if (c > '0' && c <= '9') { | |
207 | s0 = s; | |
208 | nf += nz; | |
209 | nz = 0; | |
210 | goto have_dig; | |
211 | } | |
212 | goto dig_done; | |
213 | } | |
214 | for(; c >= '0' && c <= '9'; c = *++s) { | |
215 | have_dig: | |
216 | nz++; | |
217 | if (c -= '0') { | |
218 | nf += nz; | |
219 | for(i = 1; i < nz; i++) | |
220 | if (nd++ < 9) | |
221 | y *= 10; | |
222 | else if (nd <= DBL_DIG + 1) | |
223 | z *= 10; | |
224 | if (nd++ < 9) | |
225 | y = 10*y + c; | |
226 | else if (nd <= DBL_DIG + 1) | |
227 | z = 10*z + c; | |
228 | nz = 0; | |
229 | } | |
230 | } | |
34e8f829 | 231 | }/*}*/ |
9385eb3d A |
232 | dig_done: |
233 | e = 0; | |
234 | if (c == 'e' || c == 'E') { | |
235 | if (!nd && !nz && !nz0) { | |
236 | goto ret0; | |
237 | } | |
238 | s00 = s; | |
239 | esign = 0; | |
240 | switch(c = *++s) { | |
241 | case '-': | |
242 | esign = 1; | |
243 | case '+': | |
244 | c = *++s; | |
245 | } | |
246 | if (c >= '0' && c <= '9') { | |
247 | while(c == '0') | |
248 | c = *++s; | |
249 | if (c > '0' && c <= '9') { | |
250 | L = c - '0'; | |
251 | s1 = s; | |
252 | while((c = *++s) >= '0' && c <= '9') | |
253 | L = 10*L + c - '0'; | |
254 | if (s - s1 > 8 || L > 19999) | |
255 | /* Avoid confusion from exponents | |
256 | * so large that e might overflow. | |
257 | */ | |
258 | e = 19999; /* safe for 16 bit ints */ | |
259 | else | |
260 | e = (int)L; | |
261 | if (esign) | |
262 | e = -e; | |
263 | } | |
264 | else | |
265 | e = 0; | |
266 | } | |
267 | else | |
268 | s = s00; | |
269 | } | |
270 | if (!nd) { | |
271 | if (!nz && !nz0) { | |
272 | #ifdef INFNAN_CHECK | |
273 | /* Check for Nan and Infinity */ | |
274 | ULong bits[2]; | |
6465356a | 275 | static CONST FPI fpinan = /* only 52 explicit bits */ |
9385eb3d | 276 | { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; |
3d9156a7 A |
277 | if (!decpt) |
278 | switch(c) { | |
9385eb3d A |
279 | case 'i': |
280 | case 'I': | |
281 | if (match(&s,"nf")) { | |
282 | --s; | |
283 | if (!match(&s,"inity")) | |
284 | ++s; | |
1f2f436a A |
285 | word0(&rv) = 0x7ff00000; |
286 | word1(&rv) = 0; | |
9385eb3d A |
287 | goto ret; |
288 | } | |
289 | break; | |
290 | case 'n': | |
291 | case 'N': | |
292 | if (match(&s, "an")) { | |
293 | #ifndef No_Hex_NaN | |
294 | if (*s == '(' /*)*/ | |
295 | && hexnan(&s, &fpinan, bits) | |
296 | == STRTOG_NaNbits) { | |
1f2f436a A |
297 | word0(&rv) = 0x7ff00000 | bits[1]; |
298 | word1(&rv) = bits[0]; | |
9385eb3d A |
299 | } |
300 | else { | |
3d9156a7 | 301 | #endif |
1f2f436a A |
302 | word0(&rv) = NAN_WORD0; |
303 | word1(&rv) = NAN_WORD1; | |
3d9156a7 | 304 | #ifndef No_Hex_NaN |
9385eb3d A |
305 | } |
306 | #endif | |
307 | goto ret; | |
308 | } | |
309 | } | |
310 | #endif /* INFNAN_CHECK */ | |
311 | ret0: | |
312 | s = s00; | |
313 | sign = 0; | |
314 | } | |
315 | goto ret; | |
316 | } | |
ad3c9f2a A |
317 | #define FPIEMIN (1-1023-53+1) // fpi.emin |
318 | #define FPINBITS 52 // fpi.nbits | |
319 | TRUNCATE_DIGITS(s0, strunc, nd, nd0, nf, FPINBITS, FPIEMIN, dplen); | |
9385eb3d A |
320 | e1 = e -= nf; |
321 | ||
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 | |
325 | * 10**e */ | |
326 | ||
327 | if (!nd0) | |
328 | nd0 = nd; | |
329 | k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; | |
1f2f436a | 330 | dval(&rv) = y; |
9385eb3d A |
331 | if (k > 9) { |
332 | #ifdef SET_INEXACT | |
333 | if (k > DBL_DIG) | |
334 | oldinexact = get_inexact(); | |
335 | #endif | |
1f2f436a | 336 | dval(&rv) = tens[k - 9] * dval(&rv) + z; |
9385eb3d A |
337 | } |
338 | bd0 = 0; | |
339 | if (nd <= DBL_DIG | |
340 | #ifndef RND_PRODQUOT | |
341 | #ifndef Honor_FLT_ROUNDS | |
342 | && Flt_Rounds == 1 | |
343 | #endif | |
344 | #endif | |
345 | ) { | |
346 | if (!e) | |
347 | goto ret; | |
348 | if (e > 0) { | |
349 | if (e <= Ten_pmax) { | |
350 | #ifdef VAX | |
351 | goto vax_ovfl_check; | |
352 | #else | |
353 | #ifdef Honor_FLT_ROUNDS | |
354 | /* round correctly FLT_ROUNDS = 2 or 3 */ | |
355 | if (sign) { | |
ad3c9f2a | 356 | dval(&rv) = -dval(&rv); |
9385eb3d A |
357 | sign = 0; |
358 | } | |
359 | #endif | |
1f2f436a | 360 | /* rv = */ rounded_product(dval(&rv), tens[e]); |
9385eb3d A |
361 | goto ret; |
362 | #endif | |
363 | } | |
364 | i = DBL_DIG - nd; | |
365 | if (e <= Ten_pmax + i) { | |
366 | /* A fancier test would sometimes let us do | |
367 | * this for larger i values. | |
368 | */ | |
369 | #ifdef Honor_FLT_ROUNDS | |
370 | /* round correctly FLT_ROUNDS = 2 or 3 */ | |
371 | if (sign) { | |
ad3c9f2a | 372 | dval(&rv) = -dval(&rv); |
9385eb3d A |
373 | sign = 0; |
374 | } | |
375 | #endif | |
376 | e -= i; | |
1f2f436a | 377 | dval(&rv) *= tens[i]; |
9385eb3d A |
378 | #ifdef VAX |
379 | /* VAX exponent range is so narrow we must | |
380 | * worry about overflow here... | |
381 | */ | |
382 | vax_ovfl_check: | |
1f2f436a A |
383 | word0(&rv) -= P*Exp_msk1; |
384 | /* rv = */ rounded_product(dval(&rv), tens[e]); | |
385 | if ((word0(&rv) & Exp_mask) | |
9385eb3d A |
386 | > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) |
387 | goto ovfl; | |
1f2f436a | 388 | word0(&rv) += P*Exp_msk1; |
9385eb3d | 389 | #else |
1f2f436a | 390 | /* rv = */ rounded_product(dval(&rv), tens[e]); |
9385eb3d A |
391 | #endif |
392 | goto ret; | |
393 | } | |
394 | } | |
395 | #ifndef Inaccurate_Divide | |
396 | else if (e >= -Ten_pmax) { | |
397 | #ifdef Honor_FLT_ROUNDS | |
398 | /* round correctly FLT_ROUNDS = 2 or 3 */ | |
399 | if (sign) { | |
ad3c9f2a | 400 | dval(&rv) = -dval(&rv); |
9385eb3d A |
401 | sign = 0; |
402 | } | |
403 | #endif | |
1f2f436a | 404 | /* rv = */ rounded_quotient(dval(&rv), tens[-e]); |
9385eb3d A |
405 | goto ret; |
406 | } | |
407 | #endif | |
408 | } | |
409 | e1 += nd - k; | |
410 | ||
411 | #ifdef IEEE_Arith | |
412 | #ifdef SET_INEXACT | |
413 | inexact = 1; | |
414 | if (k <= DBL_DIG) | |
415 | oldinexact = get_inexact(); | |
416 | #endif | |
417 | #ifdef Avoid_Underflow | |
418 | scale = 0; | |
419 | #endif | |
420 | #ifdef Honor_FLT_ROUNDS | |
34e8f829 | 421 | if (Rounding >= 2) { |
9385eb3d | 422 | if (sign) |
34e8f829 | 423 | Rounding = Rounding == 2 ? 0 : 2; |
9385eb3d | 424 | else |
34e8f829 A |
425 | if (Rounding != 2) |
426 | Rounding = 0; | |
9385eb3d A |
427 | } |
428 | #endif | |
429 | #endif /*IEEE_Arith*/ | |
430 | ||
431 | /* Get starting approximation = rv * 10**e1 */ | |
432 | ||
433 | if (e1 > 0) { | |
434 | if ( (i = e1 & 15) !=0) | |
1f2f436a | 435 | dval(&rv) *= tens[i]; |
9385eb3d A |
436 | if (e1 &= ~15) { |
437 | if (e1 > DBL_MAX_10_EXP) { | |
438 | ovfl: | |
439 | #ifndef NO_ERRNO | |
440 | errno = ERANGE; | |
441 | #endif | |
442 | /* Can't trust HUGE_VAL */ | |
443 | #ifdef IEEE_Arith | |
444 | #ifdef Honor_FLT_ROUNDS | |
34e8f829 | 445 | switch(Rounding) { |
9385eb3d A |
446 | case 0: /* toward 0 */ |
447 | case 3: /* toward -infinity */ | |
1f2f436a A |
448 | word0(&rv) = Big0; |
449 | word1(&rv) = Big1; | |
9385eb3d A |
450 | break; |
451 | default: | |
1f2f436a A |
452 | word0(&rv) = Exp_mask; |
453 | word1(&rv) = 0; | |
9385eb3d A |
454 | } |
455 | #else /*Honor_FLT_ROUNDS*/ | |
1f2f436a A |
456 | word0(&rv) = Exp_mask; |
457 | word1(&rv) = 0; | |
9385eb3d A |
458 | #endif /*Honor_FLT_ROUNDS*/ |
459 | #ifdef SET_INEXACT | |
460 | /* set overflow bit */ | |
1f2f436a A |
461 | dval(&rv0) = 1e300; |
462 | dval(&rv0) *= dval(&rv0); | |
9385eb3d A |
463 | #endif |
464 | #else /*IEEE_Arith*/ | |
1f2f436a A |
465 | word0(&rv) = Big0; |
466 | word1(&rv) = Big1; | |
9385eb3d A |
467 | #endif /*IEEE_Arith*/ |
468 | if (bd0) | |
469 | goto retfree; | |
470 | goto ret; | |
471 | } | |
472 | e1 >>= 4; | |
473 | for(j = 0; e1 > 1; j++, e1 >>= 1) | |
474 | if (e1 & 1) | |
1f2f436a | 475 | dval(&rv) *= bigtens[j]; |
9385eb3d | 476 | /* The last multiplication could overflow. */ |
1f2f436a A |
477 | word0(&rv) -= P*Exp_msk1; |
478 | dval(&rv) *= bigtens[j]; | |
479 | if ((z = word0(&rv) & Exp_mask) | |
9385eb3d A |
480 | > Exp_msk1*(DBL_MAX_EXP+Bias-P)) |
481 | goto ovfl; | |
482 | if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { | |
483 | /* set to largest number */ | |
484 | /* (Can't trust DBL_MAX) */ | |
1f2f436a A |
485 | word0(&rv) = Big0; |
486 | word1(&rv) = Big1; | |
9385eb3d A |
487 | } |
488 | else | |
1f2f436a | 489 | word0(&rv) += P*Exp_msk1; |
9385eb3d A |
490 | } |
491 | } | |
492 | else if (e1 < 0) { | |
493 | e1 = -e1; | |
494 | if ( (i = e1 & 15) !=0) | |
1f2f436a | 495 | dval(&rv) /= tens[i]; |
9385eb3d A |
496 | if (e1 >>= 4) { |
497 | if (e1 >= 1 << n_bigtens) | |
498 | goto undfl; | |
499 | #ifdef Avoid_Underflow | |
500 | if (e1 & Scale_Bit) | |
501 | scale = 2*P; | |
502 | for(j = 0; e1 > 0; j++, e1 >>= 1) | |
503 | if (e1 & 1) | |
1f2f436a A |
504 | dval(&rv) *= tinytens[j]; |
505 | if (scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) | |
9385eb3d A |
506 | >> Exp_shift)) > 0) { |
507 | /* scaled rv is denormal; zap j low bits */ | |
508 | if (j >= 32) { | |
1f2f436a | 509 | word1(&rv) = 0; |
9385eb3d | 510 | if (j >= 53) |
1f2f436a | 511 | word0(&rv) = (P+2)*Exp_msk1; |
9385eb3d | 512 | else |
1f2f436a | 513 | word0(&rv) &= 0xffffffff << (j-32); |
9385eb3d A |
514 | } |
515 | else | |
1f2f436a | 516 | word1(&rv) &= 0xffffffff << j; |
9385eb3d A |
517 | } |
518 | #else | |
519 | for(j = 0; e1 > 1; j++, e1 >>= 1) | |
520 | if (e1 & 1) | |
1f2f436a | 521 | dval(&rv) *= tinytens[j]; |
9385eb3d | 522 | /* The last multiplication could underflow. */ |
1f2f436a A |
523 | dval(&rv0) = dval(&rv); |
524 | dval(&rv) *= tinytens[j]; | |
525 | if (!dval(&rv)) { | |
526 | dval(&rv) = 2.*dval(&rv0); | |
527 | dval(&rv) *= tinytens[j]; | |
9385eb3d | 528 | #endif |
1f2f436a | 529 | if (!dval(&rv)) { |
9385eb3d | 530 | undfl: |
1f2f436a | 531 | dval(&rv) = 0.; |
9385eb3d A |
532 | #ifndef NO_ERRNO |
533 | errno = ERANGE; | |
534 | #endif | |
535 | if (bd0) | |
536 | goto retfree; | |
537 | goto ret; | |
538 | } | |
539 | #ifndef Avoid_Underflow | |
1f2f436a A |
540 | word0(&rv) = Tiny0; |
541 | word1(&rv) = Tiny1; | |
9385eb3d A |
542 | /* The refinement below will clean |
543 | * this approximation up. | |
544 | */ | |
545 | } | |
546 | #endif | |
547 | } | |
548 | } | |
549 | ||
550 | /* Now the hard part -- adjusting rv to the correct value.*/ | |
551 | ||
552 | /* Put digits into bd: true value = bd * 10^e */ | |
553 | ||
1f2f436a | 554 | bd0 = s2b(s0, nd0, nd, y, dplen); |
9385eb3d A |
555 | |
556 | for(;;) { | |
557 | bd = Balloc(bd0->k); | |
558 | Bcopy(bd, bd0); | |
1f2f436a | 559 | bb = d2b(dval(&rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ |
9385eb3d A |
560 | bs = i2b(1); |
561 | ||
562 | if (e >= 0) { | |
563 | bb2 = bb5 = 0; | |
564 | bd2 = bd5 = e; | |
565 | } | |
566 | else { | |
567 | bb2 = bb5 = -e; | |
568 | bd2 = bd5 = 0; | |
569 | } | |
570 | if (bbe >= 0) | |
571 | bb2 += bbe; | |
572 | else | |
573 | bd2 -= bbe; | |
574 | bs2 = bb2; | |
575 | #ifdef Honor_FLT_ROUNDS | |
34e8f829 | 576 | if (Rounding != 1) |
9385eb3d A |
577 | bs2++; |
578 | #endif | |
579 | #ifdef Avoid_Underflow | |
580 | j = bbe - scale; | |
1f2f436a | 581 | i = j + bbbits - 1; /* logb(&rv) */ |
9385eb3d A |
582 | if (i < Emin) /* denormal */ |
583 | j += P - Emin; | |
584 | else | |
585 | j = P + 1 - bbbits; | |
586 | #else /*Avoid_Underflow*/ | |
587 | #ifdef Sudden_Underflow | |
588 | #ifdef IBM | |
589 | j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); | |
590 | #else | |
591 | j = P + 1 - bbbits; | |
592 | #endif | |
593 | #else /*Sudden_Underflow*/ | |
594 | j = bbe; | |
1f2f436a | 595 | i = j + bbbits - 1; /* logb(&rv) */ |
9385eb3d A |
596 | if (i < Emin) /* denormal */ |
597 | j += P - Emin; | |
598 | else | |
599 | j = P + 1 - bbbits; | |
600 | #endif /*Sudden_Underflow*/ | |
601 | #endif /*Avoid_Underflow*/ | |
602 | bb2 += j; | |
603 | bd2 += j; | |
604 | #ifdef Avoid_Underflow | |
605 | bd2 += scale; | |
606 | #endif | |
607 | i = bb2 < bd2 ? bb2 : bd2; | |
608 | if (i > bs2) | |
609 | i = bs2; | |
610 | if (i > 0) { | |
611 | bb2 -= i; | |
612 | bd2 -= i; | |
613 | bs2 -= i; | |
614 | } | |
615 | if (bb5 > 0) { | |
616 | bs = pow5mult(bs, bb5); | |
617 | bb1 = mult(bs, bb); | |
618 | Bfree(bb); | |
619 | bb = bb1; | |
620 | } | |
621 | if (bb2 > 0) | |
622 | bb = lshift(bb, bb2); | |
623 | if (bd5 > 0) | |
624 | bd = pow5mult(bd, bd5); | |
625 | if (bd2 > 0) | |
626 | bd = lshift(bd, bd2); | |
627 | if (bs2 > 0) | |
628 | bs = lshift(bs, bs2); | |
629 | delta = diff(bb, bd); | |
630 | dsign = delta->sign; | |
631 | delta->sign = 0; | |
632 | i = cmp(delta, bs); | |
633 | #ifdef Honor_FLT_ROUNDS | |
34e8f829 | 634 | if (Rounding != 1) { |
9385eb3d A |
635 | if (i < 0) { |
636 | /* Error is less than an ulp */ | |
637 | if (!delta->x[0] && delta->wds <= 1) { | |
638 | /* exact */ | |
639 | #ifdef SET_INEXACT | |
640 | inexact = 0; | |
641 | #endif | |
642 | break; | |
643 | } | |
34e8f829 | 644 | if (Rounding) { |
9385eb3d | 645 | if (dsign) { |
1f2f436a | 646 | dval(&adj) = 1.; |
9385eb3d A |
647 | goto apply_adj; |
648 | } | |
649 | } | |
650 | else if (!dsign) { | |
1f2f436a A |
651 | dval(&adj) = -1.; |
652 | if (!word1(&rv) | |
653 | && !(word0(&rv) & Frac_mask)) { | |
654 | y = word0(&rv) & Exp_mask; | |
9385eb3d A |
655 | #ifdef Avoid_Underflow |
656 | if (!scale || y > 2*P*Exp_msk1) | |
657 | #else | |
658 | if (y) | |
659 | #endif | |
660 | { | |
661 | delta = lshift(delta,Log2P); | |
662 | if (cmp(delta, bs) <= 0) | |
1f2f436a | 663 | dval(&adj) = -0.5; |
9385eb3d A |
664 | } |
665 | } | |
666 | apply_adj: | |
667 | #ifdef Avoid_Underflow | |
1f2f436a | 668 | if (scale && (y = word0(&rv) & Exp_mask) |
9385eb3d | 669 | <= 2*P*Exp_msk1) |
1f2f436a | 670 | word0(&adj) += (2*P+1)*Exp_msk1 - y; |
9385eb3d A |
671 | #else |
672 | #ifdef Sudden_Underflow | |
1f2f436a | 673 | if ((word0(&rv) & Exp_mask) <= |
9385eb3d | 674 | P*Exp_msk1) { |
1f2f436a A |
675 | word0(&rv) += P*Exp_msk1; |
676 | dval(&rv) += adj*ulp(&rv); | |
677 | word0(&rv) -= P*Exp_msk1; | |
9385eb3d A |
678 | } |
679 | else | |
680 | #endif /*Sudden_Underflow*/ | |
681 | #endif /*Avoid_Underflow*/ | |
ad3c9f2a | 682 | dval(&rv) += dval(&adj)*ulp(&rv); |
9385eb3d A |
683 | } |
684 | break; | |
685 | } | |
1f2f436a | 686 | dval(&adj) = ratio(delta, bs); |
ad3c9f2a | 687 | if (dval(&adj) < 1.) |
1f2f436a | 688 | dval(&adj) = 1.; |
ad3c9f2a | 689 | if (dval(&adj) <= 0x7ffffffe) { |
1f2f436a | 690 | /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */ |
ad3c9f2a A |
691 | y = dval(&adj); |
692 | if (y != dval(&adj)) { | |
34e8f829 | 693 | if (!((Rounding>>1) ^ dsign)) |
9385eb3d | 694 | y++; |
1f2f436a | 695 | dval(&adj) = y; |
9385eb3d A |
696 | } |
697 | } | |
698 | #ifdef Avoid_Underflow | |
1f2f436a A |
699 | if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) |
700 | word0(&adj) += (2*P+1)*Exp_msk1 - y; | |
9385eb3d A |
701 | #else |
702 | #ifdef Sudden_Underflow | |
1f2f436a A |
703 | if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { |
704 | word0(&rv) += P*Exp_msk1; | |
705 | dval(&adj) *= ulp(&rv); | |
9385eb3d | 706 | if (dsign) |
1f2f436a | 707 | dval(&rv) += adj; |
9385eb3d | 708 | else |
1f2f436a A |
709 | dval(&rv) -= adj; |
710 | word0(&rv) -= P*Exp_msk1; | |
9385eb3d A |
711 | goto cont; |
712 | } | |
713 | #endif /*Sudden_Underflow*/ | |
714 | #endif /*Avoid_Underflow*/ | |
1f2f436a | 715 | dval(&adj) *= ulp(&rv); |
34e8f829 | 716 | if (dsign) { |
1f2f436a | 717 | if (word0(&rv) == Big0 && word1(&rv) == Big1) |
34e8f829 | 718 | goto ovfl; |
ad3c9f2a | 719 | dval(&rv) += dval(&adj); |
34e8f829 | 720 | } |
9385eb3d | 721 | else |
ad3c9f2a | 722 | dval(&rv) -= dval(&adj); |
9385eb3d A |
723 | goto cont; |
724 | } | |
725 | #endif /*Honor_FLT_ROUNDS*/ | |
726 | ||
727 | if (i < 0) { | |
728 | /* Error is less than half an ulp -- check for | |
729 | * special case of mantissa a power of two. | |
730 | */ | |
1f2f436a | 731 | if (dsign || word1(&rv) || word0(&rv) & Bndry_mask |
9385eb3d A |
732 | #ifdef IEEE_Arith |
733 | #ifdef Avoid_Underflow | |
1f2f436a | 734 | || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 |
9385eb3d | 735 | #else |
1f2f436a | 736 | || (word0(&rv) & Exp_mask) <= Exp_msk1 |
9385eb3d A |
737 | #endif |
738 | #endif | |
739 | ) { | |
740 | #ifdef SET_INEXACT | |
741 | if (!delta->x[0] && delta->wds <= 1) | |
742 | inexact = 0; | |
743 | #endif | |
744 | break; | |
745 | } | |
746 | if (!delta->x[0] && delta->wds <= 1) { | |
747 | /* exact result */ | |
748 | #ifdef SET_INEXACT | |
749 | inexact = 0; | |
750 | #endif | |
751 | break; | |
752 | } | |
753 | delta = lshift(delta,Log2P); | |
754 | if (cmp(delta, bs) > 0) | |
755 | goto drop_down; | |
756 | break; | |
757 | } | |
758 | if (i == 0) { | |
759 | /* exactly half-way between */ | |
760 | if (dsign) { | |
1f2f436a A |
761 | if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 |
762 | && word1(&rv) == ( | |
9385eb3d | 763 | #ifdef Avoid_Underflow |
1f2f436a | 764 | (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) |
9385eb3d A |
765 | ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : |
766 | #endif | |
767 | 0xffffffff)) { | |
768 | /*boundary case -- increment exponent*/ | |
1f2f436a | 769 | word0(&rv) = (word0(&rv) & Exp_mask) |
9385eb3d A |
770 | + Exp_msk1 |
771 | #ifdef IBM | |
772 | | Exp_msk1 >> 4 | |
773 | #endif | |
774 | ; | |
1f2f436a | 775 | word1(&rv) = 0; |
9385eb3d A |
776 | #ifdef Avoid_Underflow |
777 | dsign = 0; | |
778 | #endif | |
779 | break; | |
780 | } | |
781 | } | |
1f2f436a | 782 | else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { |
9385eb3d A |
783 | drop_down: |
784 | /* boundary case -- decrement exponent */ | |
785 | #ifdef Sudden_Underflow /*{{*/ | |
1f2f436a | 786 | L = word0(&rv) & Exp_mask; |
9385eb3d A |
787 | #ifdef IBM |
788 | if (L < Exp_msk1) | |
789 | #else | |
790 | #ifdef Avoid_Underflow | |
791 | if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) | |
792 | #else | |
793 | if (L <= Exp_msk1) | |
794 | #endif /*Avoid_Underflow*/ | |
795 | #endif /*IBM*/ | |
796 | goto undfl; | |
797 | L -= Exp_msk1; | |
798 | #else /*Sudden_Underflow}{*/ | |
799 | #ifdef Avoid_Underflow | |
800 | if (scale) { | |
1f2f436a | 801 | L = word0(&rv) & Exp_mask; |
9385eb3d A |
802 | if (L <= (2*P+1)*Exp_msk1) { |
803 | if (L > (P+2)*Exp_msk1) | |
804 | /* round even ==> */ | |
805 | /* accept rv */ | |
806 | break; | |
807 | /* rv = smallest denormal */ | |
808 | goto undfl; | |
809 | } | |
810 | } | |
811 | #endif /*Avoid_Underflow*/ | |
1f2f436a | 812 | L = (word0(&rv) & Exp_mask) - Exp_msk1; |
34e8f829 | 813 | #endif /*Sudden_Underflow}}*/ |
1f2f436a A |
814 | word0(&rv) = L | Bndry_mask1; |
815 | word1(&rv) = 0xffffffff; | |
9385eb3d A |
816 | #ifdef IBM |
817 | goto cont; | |
818 | #else | |
819 | break; | |
820 | #endif | |
821 | } | |
822 | #ifndef ROUND_BIASED | |
1f2f436a | 823 | if (!(word1(&rv) & LSB)) |
9385eb3d A |
824 | break; |
825 | #endif | |
826 | if (dsign) | |
1f2f436a | 827 | dval(&rv) += ulp(&rv); |
9385eb3d A |
828 | #ifndef ROUND_BIASED |
829 | else { | |
1f2f436a | 830 | dval(&rv) -= ulp(&rv); |
9385eb3d | 831 | #ifndef Sudden_Underflow |
1f2f436a | 832 | if (!dval(&rv)) |
9385eb3d A |
833 | goto undfl; |
834 | #endif | |
835 | } | |
836 | #ifdef Avoid_Underflow | |
837 | dsign = 1 - dsign; | |
838 | #endif | |
839 | #endif | |
840 | break; | |
841 | } | |
842 | if ((aadj = ratio(delta, bs)) <= 2.) { | |
843 | if (dsign) | |
1f2f436a A |
844 | aadj = dval(&aadj1) = 1.; |
845 | else if (word1(&rv) || word0(&rv) & Bndry_mask) { | |
9385eb3d | 846 | #ifndef Sudden_Underflow |
1f2f436a | 847 | if (word1(&rv) == Tiny1 && !word0(&rv)) |
9385eb3d A |
848 | goto undfl; |
849 | #endif | |
850 | aadj = 1.; | |
1f2f436a | 851 | dval(&aadj1) = -1.; |
9385eb3d A |
852 | } |
853 | else { | |
854 | /* special case -- power of FLT_RADIX to be */ | |
855 | /* rounded down... */ | |
856 | ||
857 | if (aadj < 2./FLT_RADIX) | |
858 | aadj = 1./FLT_RADIX; | |
859 | else | |
860 | aadj *= 0.5; | |
1f2f436a | 861 | dval(&aadj1) = -aadj; |
9385eb3d A |
862 | } |
863 | } | |
864 | else { | |
865 | aadj *= 0.5; | |
1f2f436a | 866 | dval(&aadj1) = dsign ? aadj : -aadj; |
9385eb3d A |
867 | #ifdef Check_FLT_ROUNDS |
868 | switch(Rounding) { | |
869 | case 2: /* towards +infinity */ | |
1f2f436a | 870 | dval(&aadj1) -= 0.5; |
9385eb3d A |
871 | break; |
872 | case 0: /* towards 0 */ | |
873 | case 3: /* towards -infinity */ | |
1f2f436a | 874 | dval(&aadj1) += 0.5; |
9385eb3d A |
875 | } |
876 | #else | |
877 | if (Flt_Rounds == 0) | |
1f2f436a | 878 | dval(&aadj1) += 0.5; |
9385eb3d A |
879 | #endif /*Check_FLT_ROUNDS*/ |
880 | } | |
1f2f436a | 881 | y = word0(&rv) & Exp_mask; |
9385eb3d A |
882 | |
883 | /* Check for overflow */ | |
884 | ||
885 | if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { | |
1f2f436a A |
886 | dval(&rv0) = dval(&rv); |
887 | word0(&rv) -= P*Exp_msk1; | |
888 | dval(&adj) = dval(&aadj1) * ulp(&rv); | |
889 | dval(&rv) += dval(&adj); | |
890 | if ((word0(&rv) & Exp_mask) >= | |
9385eb3d | 891 | Exp_msk1*(DBL_MAX_EXP+Bias-P)) { |
1f2f436a | 892 | if (word0(&rv0) == Big0 && word1(&rv0) == Big1) |
9385eb3d | 893 | goto ovfl; |
1f2f436a A |
894 | word0(&rv) = Big0; |
895 | word1(&rv) = Big1; | |
9385eb3d A |
896 | goto cont; |
897 | } | |
898 | else | |
1f2f436a | 899 | word0(&rv) += P*Exp_msk1; |
9385eb3d A |
900 | } |
901 | else { | |
902 | #ifdef Avoid_Underflow | |
903 | if (scale && y <= 2*P*Exp_msk1) { | |
904 | if (aadj <= 0x7fffffff) { | |
905 | if ((z = aadj) <= 0) | |
906 | z = 1; | |
907 | aadj = z; | |
1f2f436a | 908 | dval(&aadj1) = dsign ? aadj : -aadj; |
9385eb3d | 909 | } |
1f2f436a | 910 | word0(&aadj1) += (2*P+1)*Exp_msk1 - y; |
9385eb3d | 911 | } |
1f2f436a A |
912 | dval(&adj) = dval(&aadj1) * ulp(&rv); |
913 | dval(&rv) += dval(&adj); | |
9385eb3d A |
914 | #else |
915 | #ifdef Sudden_Underflow | |
1f2f436a A |
916 | if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { |
917 | dval(&rv0) = dval(&rv); | |
918 | word0(&rv) += P*Exp_msk1; | |
919 | dval(&adj) = dval(&aadj1) * ulp(&rv); | |
920 | dval(&rv) += adj; | |
9385eb3d | 921 | #ifdef IBM |
1f2f436a | 922 | if ((word0(&rv) & Exp_mask) < P*Exp_msk1) |
9385eb3d | 923 | #else |
1f2f436a | 924 | if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) |
9385eb3d A |
925 | #endif |
926 | { | |
1f2f436a A |
927 | if (word0(&rv0) == Tiny0 |
928 | && word1(&rv0) == Tiny1) | |
9385eb3d | 929 | goto undfl; |
1f2f436a A |
930 | word0(&rv) = Tiny0; |
931 | word1(&rv) = Tiny1; | |
9385eb3d A |
932 | goto cont; |
933 | } | |
934 | else | |
1f2f436a | 935 | word0(&rv) -= P*Exp_msk1; |
9385eb3d A |
936 | } |
937 | else { | |
1f2f436a A |
938 | dval(&adj) = dval(&aadj1) * ulp(&rv); |
939 | dval(&rv) += adj; | |
9385eb3d A |
940 | } |
941 | #else /*Sudden_Underflow*/ | |
1f2f436a A |
942 | /* Compute dval(&adj) so that the IEEE rounding rules will |
943 | * correctly round rv + dval(&adj) in some half-way cases. | |
944 | * If rv * ulp(&rv) is denormalized (i.e., | |
9385eb3d A |
945 | * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid |
946 | * trouble from bits lost to denormalization; | |
947 | * example: 1.2e-307 . | |
948 | */ | |
949 | if (y <= (P-1)*Exp_msk1 && aadj > 1.) { | |
1f2f436a | 950 | dval(&aadj1) = (double)(int)(aadj + 0.5); |
9385eb3d | 951 | if (!dsign) |
1f2f436a | 952 | dval(&aadj1) = -dval(&aadj1); |
9385eb3d | 953 | } |
1f2f436a A |
954 | dval(&adj) = dval(&aadj1) * ulp(&rv); |
955 | dval(&rv) += adj; | |
9385eb3d A |
956 | #endif /*Sudden_Underflow*/ |
957 | #endif /*Avoid_Underflow*/ | |
958 | } | |
1f2f436a | 959 | z = word0(&rv) & Exp_mask; |
9385eb3d A |
960 | #ifndef SET_INEXACT |
961 | #ifdef Avoid_Underflow | |
962 | if (!scale) | |
963 | #endif | |
964 | if (y == z) { | |
965 | /* Can we stop now? */ | |
966 | L = (Long)aadj; | |
967 | aadj -= L; | |
968 | /* The tolerances below are conservative. */ | |
1f2f436a | 969 | if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { |
9385eb3d A |
970 | if (aadj < .4999999 || aadj > .5000001) |
971 | break; | |
972 | } | |
973 | else if (aadj < .4999999/FLT_RADIX) | |
974 | break; | |
975 | } | |
976 | #endif | |
977 | cont: | |
978 | Bfree(bb); | |
979 | Bfree(bd); | |
980 | Bfree(bs); | |
981 | Bfree(delta); | |
982 | } | |
983 | #ifdef SET_INEXACT | |
984 | if (inexact) { | |
985 | if (!oldinexact) { | |
1f2f436a A |
986 | word0(&rv0) = Exp_1 + (70 << Exp_shift); |
987 | word1(&rv0) = 0; | |
988 | dval(&rv0) += 1.; | |
9385eb3d A |
989 | } |
990 | } | |
991 | else if (!oldinexact) | |
992 | clear_inexact(); | |
993 | #endif | |
994 | #ifdef Avoid_Underflow | |
995 | if (scale) { | |
1f2f436a A |
996 | word0(&rv0) = Exp_1 - 2*P*Exp_msk1; |
997 | word1(&rv0) = 0; | |
998 | dval(&rv) *= dval(&rv0); | |
9385eb3d A |
999 | #ifndef NO_ERRNO |
1000 | /* try to avoid the bug of testing an 8087 register value */ | |
ad3c9f2a | 1001 | #if defined(IEEE_Arith) && __DARWIN_UNIX03 |
1f2f436a | 1002 | if (!(word0(&rv) & Exp_mask)) |
34e8f829 | 1003 | #else |
1f2f436a | 1004 | if (word0(&rv) == 0 && word1(&rv) == 0) |
34e8f829 | 1005 | #endif |
9385eb3d A |
1006 | errno = ERANGE; |
1007 | #endif | |
1008 | } | |
1009 | #endif /* Avoid_Underflow */ | |
1010 | #ifdef SET_INEXACT | |
1f2f436a | 1011 | if (inexact && !(word0(&rv) & Exp_mask)) { |
9385eb3d | 1012 | /* set underflow bit */ |
1f2f436a A |
1013 | dval(&rv0) = 1e-300; |
1014 | dval(&rv0) *= dval(&rv0); | |
9385eb3d A |
1015 | } |
1016 | #endif | |
1017 | retfree: | |
1018 | Bfree(bb); | |
1019 | Bfree(bd); | |
1020 | Bfree(bs); | |
1021 | Bfree(bd0); | |
1022 | Bfree(delta); | |
1023 | ret: | |
1024 | if (se) | |
1025 | *se = (char *)s; | |
ad3c9f2a A |
1026 | if (strunc) |
1027 | #ifdef FREE | |
1028 | FREE(strunc); | |
1029 | #else | |
1030 | free(strunc); | |
1031 | #endif | |
1f2f436a | 1032 | return sign ? -dval(&rv) : dval(&rv); |
9385eb3d A |
1033 | } |
1034 | ||
ad3c9f2a A |
1035 | double |
1036 | strtod | |
1037 | #ifdef KR_headers | |
1038 | (s00, se) CONST char *s00; char **se; | |
1039 | #else | |
1040 | (CONST char *s00, char **se) | |
1041 | #endif | |
1042 | { | |
1043 | return strtod_l(s00, se, __current_locale()); | |
1044 | } |