File: | src/lib/libc/gdtoa/strtodg.c |
Warning: | line 1002, column 4 Value stored to 'j' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
29 | /* Please send bug reports to David M. Gay (dmg at acm dot org, |
30 | * with " at " changed at "@" and " dot " changed to "."). */ |
31 | |
32 | #include "gdtoaimp.h" |
33 | |
34 | #ifdef USE_LOCALE1 |
35 | #include "locale.h" |
36 | #endif |
37 | |
38 | static CONSTconst int |
39 | fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, |
40 | 24, 26, 28, 31, 33, 35, 38, 40, 42, 45, |
41 | 47, 49, 52 |
42 | #ifdef VAX |
43 | , 54, 56 |
44 | #endif |
45 | }; |
46 | |
47 | Bigint * |
48 | #ifdef KR_headers |
49 | increment__increment_D2A(b) Bigint *b; |
50 | #else |
51 | increment__increment_D2A(Bigint *b) |
52 | #endif |
53 | { |
54 | ULong *x, *xe; |
55 | Bigint *b1; |
56 | #ifdef Pack_16 |
57 | ULong carry = 1, y; |
58 | #endif |
59 | |
60 | x = b->x; |
61 | xe = x + b->wds; |
62 | #ifdef Pack_32 |
63 | do { |
64 | if (*x < (ULong)0xffffffffL) { |
65 | ++*x; |
66 | return b; |
67 | } |
68 | *x++ = 0; |
69 | } while(x < xe); |
70 | #else |
71 | do { |
72 | y = *x + carry; |
73 | carry = y >> 16; |
74 | *x++ = y & 0xffff; |
75 | if (!carry) |
76 | return b; |
77 | } while(x < xe); |
78 | if (carry) |
79 | #endif |
80 | { |
81 | if (b->wds >= b->maxwds) { |
82 | b1 = Balloc__Balloc_D2A(b->k+1); |
83 | if (b1 == NULL((void *)0)) |
84 | return (NULL((void *)0)); |
85 | Bcopy(b1,b)memcpy(&b1->sign,&b->sign,b->wds*sizeof(ULong ) + 2*sizeof(int)); |
86 | Bfree__Bfree_D2A(b); |
87 | b = b1; |
88 | } |
89 | b->x[b->wds++] = 1; |
90 | } |
91 | return b; |
92 | } |
93 | |
94 | void |
95 | #ifdef KR_headers |
96 | decrement__decrement_D2A(b) Bigint *b; |
97 | #else |
98 | decrement__decrement_D2A(Bigint *b) |
99 | #endif |
100 | { |
101 | ULong *x, *xe; |
102 | #ifdef Pack_16 |
103 | ULong borrow = 1, y; |
104 | #endif |
105 | |
106 | x = b->x; |
107 | xe = x + b->wds; |
108 | #ifdef Pack_32 |
109 | do { |
110 | if (*x) { |
111 | --*x; |
112 | break; |
113 | } |
114 | *x++ = 0xffffffffL; |
115 | } |
116 | while(x < xe); |
117 | #else |
118 | do { |
119 | y = *x - borrow; |
120 | borrow = (y & 0x10000) >> 16; |
121 | *x++ = y & 0xffff; |
122 | } while(borrow && x < xe); |
123 | #endif |
124 | } |
125 | |
126 | static int |
127 | #ifdef KR_headers |
128 | all_on(b, n) Bigint *b; int n; |
129 | #else |
130 | all_on(Bigint *b, int n) |
131 | #endif |
132 | { |
133 | ULong *x, *xe; |
134 | |
135 | x = b->x; |
136 | xe = x + (n >> kshift5); |
137 | while(x < xe) |
138 | if ((*x++ & ALL_ON0xffffffff) != ALL_ON0xffffffff) |
139 | return 0; |
140 | if (n &= kmask31) |
141 | return ((*x | (ALL_ON0xffffffff << n)) & ALL_ON0xffffffff) == ALL_ON0xffffffff; |
142 | return 1; |
143 | } |
144 | |
145 | Bigint * |
146 | #ifdef KR_headers |
147 | set_ones__set_ones_D2A(b, n) Bigint *b; int n; |
148 | #else |
149 | set_ones__set_ones_D2A(Bigint *b, int n) |
150 | #endif |
151 | { |
152 | int k; |
153 | ULong *x, *xe; |
154 | |
155 | k = (n + ((1 << kshift5) - 1)) >> kshift5; |
156 | if (b->k < k) { |
157 | Bfree__Bfree_D2A(b); |
158 | b = Balloc__Balloc_D2A(k); |
159 | if (b == NULL((void *)0)) |
160 | return (NULL((void *)0)); |
161 | } |
162 | k = n >> kshift5; |
163 | if (n &= kmask31) |
164 | k++; |
165 | b->wds = k; |
166 | x = b->x; |
167 | xe = x + k; |
168 | while(x < xe) |
169 | *x++ = ALL_ON0xffffffff; |
170 | if (n) |
171 | x[-1] >>= ULbits32 - n; |
172 | return b; |
173 | } |
174 | |
175 | static int |
176 | rvOK |
177 | #ifdef KR_headers |
178 | (d, fpi, exp, bits, exact, rd, irv) |
179 | U *d; FPI *fpi; Longint *exp; ULong *bits; int exact, rd, *irv; |
180 | #else |
181 | (U *d, FPI *fpi, Longint *exp, ULong *bits, int exact, int rd, int *irv) |
182 | #endif |
183 | { |
184 | Bigint *b; |
185 | ULong carry, inex, lostbits; |
186 | int bdif, e, j, k, k1, nb, rv; |
187 | |
188 | carry = rv = 0; |
189 | b = d2b__d2b_D2A(dval(d)(d)->d, &e, &bdif); |
190 | if (b == NULL((void *)0)) { |
191 | *irv = STRTOG_NoMemory; |
192 | return (1); |
193 | } |
194 | bdif -= nb = fpi->nbits; |
195 | e += bdif; |
196 | if (bdif <= 0) { |
197 | if (exact) |
198 | goto trunc; |
199 | goto ret; |
200 | } |
201 | if (P53 == nb) { |
202 | if ( |
203 | #ifndef IMPRECISE_INEXACT |
204 | exact && |
205 | #endif |
206 | fpi->rounding == |
207 | #ifdef RND_PRODQUOT |
208 | FPI_Round_near |
209 | #else |
210 | Flt_Rounds__flt_rounds() |
211 | #endif |
212 | ) goto trunc; |
213 | goto ret; |
214 | } |
215 | switch(rd) { |
216 | case 1: /* round down (toward -Infinity) */ |
217 | goto trunc; |
218 | case 2: /* round up (toward +Infinity) */ |
219 | break; |
220 | default: /* round near */ |
221 | k = bdif - 1; |
222 | if (k < 0) |
223 | goto trunc; |
224 | if (!k) { |
225 | if (!exact) |
226 | goto ret; |
227 | if (b->x[0] & 2) |
228 | break; |
229 | goto trunc; |
230 | } |
231 | if (b->x[k>>kshift5] & ((ULong)1 << (k & kmask31))) |
232 | break; |
233 | goto trunc; |
234 | } |
235 | /* "break" cases: round up 1 bit, then truncate; bdif > 0 */ |
236 | carry = 1; |
237 | trunc: |
238 | inex = lostbits = 0; |
239 | if (bdif > 0) { |
240 | if ( (lostbits = any_on__any_on_D2A(b, bdif)) !=0) |
241 | inex = STRTOG_Inexlo; |
242 | rshift__rshift_D2A(b, bdif); |
243 | if (carry) { |
244 | inex = STRTOG_Inexhi; |
245 | b = increment__increment_D2A(b); |
246 | if (b == NULL((void *)0)) { |
247 | *irv = STRTOG_NoMemory; |
248 | return (1); |
249 | } |
250 | if ( (j = nb & kmask31) !=0) |
251 | j = ULbits32 - j; |
252 | if (hi0bits(b->x[b->wds - 1])__hi0bits_D2A((ULong)(b->x[b->wds - 1])) != j) { |
253 | if (!lostbits) |
254 | lostbits = b->x[0] & 1; |
255 | rshift__rshift_D2A(b, 1); |
256 | e++; |
257 | } |
258 | } |
259 | } |
260 | else if (bdif < 0) { |
261 | b = lshift__lshift_D2A(b, -bdif); |
262 | if (b == NULL((void *)0)) { |
263 | *irv = STRTOG_NoMemory; |
264 | return (1); |
265 | } |
266 | } |
267 | if (e < fpi->emin) { |
268 | k = fpi->emin - e; |
269 | e = fpi->emin; |
270 | if (k > nb || fpi->sudden_underflow) { |
271 | b->wds = inex = 0; |
272 | *irv = STRTOG_Underflow | STRTOG_Inexlo; |
273 | } |
274 | else { |
275 | k1 = k - 1; |
276 | if (k1 > 0 && !lostbits) |
277 | lostbits = any_on__any_on_D2A(b, k1); |
278 | if (!lostbits && !exact) |
279 | goto ret; |
280 | lostbits |= |
281 | carry = b->x[k1>>kshift5] & (1 << (k1 & kmask31)); |
282 | rshift__rshift_D2A(b, k); |
283 | *irv = STRTOG_Denormal; |
284 | if (carry) { |
285 | b = increment__increment_D2A(b); |
286 | if (b == NULL((void *)0)) { |
287 | *irv = STRTOG_NoMemory; |
288 | return (1); |
289 | } |
290 | inex = STRTOG_Inexhi | STRTOG_Underflow; |
291 | } |
292 | else if (lostbits) |
293 | inex = STRTOG_Inexlo | STRTOG_Underflow; |
294 | } |
295 | } |
296 | else if (e > fpi->emax) { |
297 | e = fpi->emax + 1; |
298 | *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; |
299 | #ifndef NO_ERRNO |
300 | errno(*__errno()) = ERANGE34; |
301 | #endif |
302 | b->wds = inex = 0; |
303 | } |
304 | *exp = e; |
305 | copybits__copybits_D2A(bits, nb, b); |
306 | *irv |= inex; |
307 | rv = 1; |
308 | ret: |
309 | Bfree__Bfree_D2A(b); |
310 | return rv; |
311 | } |
312 | |
313 | static int |
314 | #ifdef KR_headers |
315 | mantbits(d) U *d; |
316 | #else |
317 | mantbits(U *d) |
318 | #endif |
319 | { |
320 | ULong L; |
321 | #ifdef VAX |
322 | L = word1(d)(d)->L[0] << 16 | word1(d)(d)->L[0] >> 16; |
323 | if (L) |
324 | #else |
325 | if ( (L = word1(d)(d)->L[0]) !=0) |
326 | #endif |
327 | return P53 - lo0bits__lo0bits_D2A(&L); |
328 | #ifdef VAX |
329 | L = word0(d)(d)->L[1] << 16 | word0(d)(d)->L[1] >> 16 | Exp_msk110x100000; |
330 | #else |
331 | L = word0(d)(d)->L[1] | Exp_msk10x100000; |
332 | #endif |
333 | return P53 - 32 - lo0bits__lo0bits_D2A(&L); |
334 | } |
335 | |
336 | int |
337 | strtodg__strtodg |
338 | #ifdef KR_headers |
339 | (s00, se, fpi, exp, bits) |
340 | CONSTconst char *s00; char **se; FPI *fpi; Longint *exp; ULong *bits; |
341 | #else |
342 | (CONSTconst char *s00, char **se, FPI *fpi, Longint *exp, ULong *bits) |
343 | #endif |
344 | { |
345 | int abe, abits, asub; |
346 | int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm; |
347 | int dsign, e, e1, e2, emin, esign, finished, i, inex, irv; |
348 | int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign; |
349 | int sudden_underflow; |
350 | CONSTconst char *s, *s0, *s1; |
351 | double adj0, tol; |
352 | Longint L; |
353 | U adj, rv; |
354 | ULong *b, *be, y, z; |
355 | Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; |
356 | #ifdef USE_LOCALE1 /*{{*/ |
357 | #ifdef NO_LOCALE_CACHE |
358 | char *decimalpoint = localeconv()->decimal_point; |
359 | int dplen = strlen(decimalpoint); |
360 | #else |
361 | char *decimalpoint; |
362 | static char *decimalpoint_cache; |
363 | static int dplen; |
364 | if (!(s0 = decimalpoint_cache)) { |
365 | s0 = localeconv()->decimal_point; |
366 | decimalpoint_cache = strdup(s0); |
367 | dplen = strlen(s0); |
368 | } |
369 | decimalpoint = (char*)s0; |
370 | #endif /*NO_LOCALE_CACHE*/ |
371 | #else /*USE_LOCALE}{*/ |
372 | #define dplen 1 |
373 | #endif /*USE_LOCALE}}*/ |
374 | |
375 | irv = STRTOG_Zero; |
376 | denorm = sign = nz0 = nz = 0; |
377 | dval(&rv)(&rv)->d = 0.; |
378 | rvb = 0; |
379 | nbits = fpi->nbits; |
380 | for(s = s00;;s++) switch(*s) { |
381 | case '-': |
382 | sign = 1; |
383 | /* no break */ |
384 | case '+': |
385 | if (*++s) |
386 | goto break2; |
387 | /* no break */ |
388 | case 0: |
389 | sign = 0; |
390 | irv = STRTOG_NoNumber; |
391 | s = s00; |
392 | goto ret; |
393 | case '\t': |
394 | case '\n': |
395 | case '\v': |
396 | case '\f': |
397 | case '\r': |
398 | case ' ': |
399 | continue; |
400 | default: |
401 | goto break2; |
402 | } |
403 | break2: |
404 | if (*s == '0') { |
405 | #ifndef NO_HEX_FP |
406 | switch(s[1]) { |
407 | case 'x': |
408 | case 'X': |
409 | irv = gethex__gethex_D2A(&s, fpi, exp, &rvb, sign); |
410 | if (irv == STRTOG_NoMemory) |
411 | return (STRTOG_NoMemory); |
412 | if (irv == STRTOG_NoNumber) { |
413 | s = s00; |
414 | sign = 0; |
415 | } |
416 | goto ret; |
417 | } |
418 | #endif |
419 | nz0 = 1; |
420 | while(*++s == '0') ; |
421 | if (!*s) |
422 | goto ret; |
423 | } |
424 | sudden_underflow = fpi->sudden_underflow; |
425 | s0 = s; |
426 | y = z = 0; |
427 | for(decpt = nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) |
428 | if (nd < 9) |
429 | y = 10*y + c - '0'; |
430 | else if (nd < 16) |
431 | z = 10*z + c - '0'; |
432 | nd0 = nd; |
433 | #ifdef USE_LOCALE1 |
434 | if (c == *decimalpoint) { |
435 | for(i = 1; decimalpoint[i]; ++i) |
436 | if (s[i] != decimalpoint[i]) |
437 | goto dig_done; |
438 | s += i; |
439 | c = *s; |
440 | #else |
441 | if (c == '.') { |
442 | c = *++s; |
443 | #endif |
444 | decpt = 1; |
445 | if (!nd) { |
446 | for(; c == '0'; c = *++s) |
447 | nz++; |
448 | if (c > '0' && c <= '9') { |
449 | s0 = s; |
450 | nf += nz; |
451 | nz = 0; |
452 | goto have_dig; |
453 | } |
454 | goto dig_done; |
455 | } |
456 | for(; c >= '0' && c <= '9'; c = *++s) { |
457 | have_dig: |
458 | nz++; |
459 | if (c -= '0') { |
460 | nf += nz; |
461 | for(i = 1; i < nz; i++) |
462 | if (nd++ < 9) |
463 | y *= 10; |
464 | else if (nd <= DBL_DIG15 + 1) |
465 | z *= 10; |
466 | if (nd++ < 9) |
467 | y = 10*y + c; |
468 | else if (nd <= DBL_DIG15 + 1) |
469 | z = 10*z + c; |
470 | nz = 0; |
471 | } |
472 | } |
473 | }/*}*/ |
474 | dig_done: |
475 | e = 0; |
476 | if (c == 'e' || c == 'E') { |
477 | if (!nd && !nz && !nz0) { |
478 | irv = STRTOG_NoNumber; |
479 | s = s00; |
480 | goto ret; |
481 | } |
482 | s00 = s; |
483 | esign = 0; |
484 | switch(c = *++s) { |
485 | case '-': |
486 | esign = 1; |
487 | case '+': |
488 | c = *++s; |
489 | } |
490 | if (c >= '0' && c <= '9') { |
491 | while(c == '0') |
492 | c = *++s; |
493 | if (c > '0' && c <= '9') { |
494 | L = c - '0'; |
495 | s1 = s; |
496 | while((c = *++s) >= '0' && c <= '9') |
497 | L = 10*L + c - '0'; |
498 | if (s - s1 > 8 || L > 19999) |
499 | /* Avoid confusion from exponents |
500 | * so large that e might overflow. |
501 | */ |
502 | e = 19999; /* safe for 16 bit ints */ |
503 | else |
504 | e = (int)L; |
505 | if (esign) |
506 | e = -e; |
507 | } |
508 | else |
509 | e = 0; |
510 | } |
511 | else |
512 | s = s00; |
513 | } |
514 | if (!nd) { |
515 | if (!nz && !nz0) { |
516 | #ifdef INFNAN_CHECK |
517 | /* Check for Nan and Infinity */ |
518 | if (!decpt) |
519 | switch(c) { |
520 | case 'i': |
521 | case 'I': |
522 | if (match__match_D2A(&s,"nf")) { |
523 | --s; |
524 | if (!match__match_D2A(&s,"inity")) |
525 | ++s; |
526 | irv = STRTOG_Infinite; |
527 | goto infnanexp; |
528 | } |
529 | break; |
530 | case 'n': |
531 | case 'N': |
532 | if (match__match_D2A(&s, "an")) { |
533 | irv = STRTOG_NaN; |
534 | *exp = fpi->emax + 1; |
535 | #ifndef No_Hex_NaN |
536 | if (*s == '(') /*)*/ |
537 | irv = hexnan__hexnan_D2A(&s, fpi, bits); |
538 | #endif |
539 | goto infnanexp; |
540 | } |
541 | } |
542 | #endif /* INFNAN_CHECK */ |
543 | irv = STRTOG_NoNumber; |
544 | s = s00; |
545 | } |
546 | goto ret; |
547 | } |
548 | |
549 | irv = STRTOG_Normal; |
550 | e1 = e -= nf; |
551 | rd = 0; |
552 | switch(fpi->rounding & 3) { |
553 | case FPI_Round_up: |
554 | rd = 2 - sign; |
555 | break; |
556 | case FPI_Round_zero: |
557 | rd = 1; |
558 | break; |
559 | case FPI_Round_down: |
560 | rd = 1 + sign; |
561 | } |
562 | |
563 | /* Now we have nd0 digits, starting at s0, followed by a |
564 | * decimal point, followed by nd-nd0 digits. The number we're |
565 | * after is the integer represented by those digits times |
566 | * 10**e */ |
567 | |
568 | if (!nd0) |
569 | nd0 = nd; |
570 | k = nd < DBL_DIG15 + 1 ? nd : DBL_DIG15 + 1; |
571 | dval(&rv)(&rv)->d = y; |
572 | if (k > 9) |
573 | dval(&rv)(&rv)->d = tens__tens_D2A[k - 9] * dval(&rv)(&rv)->d + z; |
574 | bd0 = 0; |
575 | if (nbits <= P53 && nd <= DBL_DIG15) { |
576 | if (!e) { |
577 | if (rvOK(&rv, fpi, exp, bits, 1, rd, &irv)) { |
578 | if (irv == STRTOG_NoMemory) |
579 | return (STRTOG_NoMemory); |
580 | goto ret; |
581 | } |
582 | } |
583 | else if (e > 0) { |
584 | if (e <= Ten_pmax22) { |
585 | #ifdef VAX |
586 | goto vax_ovfl_check; |
587 | #else |
588 | i = fivesbits[e] + mantbits(&rv) <= P53; |
589 | /* rv = */ rounded_product(dval(&rv), tens[e])(&rv)->d *= __tens_D2A[e]; |
590 | if (rvOK(&rv, fpi, exp, bits, i, rd, &irv)) { |
591 | if (irv == STRTOG_NoMemory) |
592 | return (STRTOG_NoMemory); |
593 | goto ret; |
594 | } |
595 | e1 -= e; |
596 | goto rv_notOK; |
597 | #endif |
598 | } |
599 | i = DBL_DIG15 - nd; |
600 | if (e <= Ten_pmax22 + i) { |
601 | /* A fancier test would sometimes let us do |
602 | * this for larger i values. |
603 | */ |
604 | e2 = e - i; |
605 | e1 -= i; |
606 | dval(&rv)(&rv)->d *= tens__tens_D2A[i]; |
607 | #ifdef VAX |
608 | /* VAX exponent range is so narrow we must |
609 | * worry about overflow here... |
610 | */ |
611 | vax_ovfl_check: |
612 | dval(&adj)(&adj)->d = dval(&rv)(&rv)->d; |
613 | word0(&adj)(&adj)->L[1] -= P53*Exp_msk10x100000; |
614 | /* adj = */ rounded_product(dval(&adj), tens[e2])(&adj)->d *= __tens_D2A[e2]; |
615 | if ((word0(&adj)(&adj)->L[1] & Exp_mask0x7ff00000) |
616 | > Exp_msk10x100000*(DBL_MAX_EXP1024+Bias1023-1-P53)) |
617 | goto rv_notOK; |
618 | word0(&adj)(&adj)->L[1] += P53*Exp_msk10x100000; |
619 | dval(&rv)(&rv)->d = dval(&adj)(&adj)->d; |
620 | #else |
621 | /* rv = */ rounded_product(dval(&rv), tens[e2])(&rv)->d *= __tens_D2A[e2]; |
622 | #endif |
623 | if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) { |
624 | if (irv == STRTOG_NoMemory) |
625 | return (STRTOG_NoMemory); |
626 | goto ret; |
627 | } |
628 | e1 -= e2; |
629 | } |
630 | } |
631 | #ifndef Inaccurate_Divide |
632 | else if (e >= -Ten_pmax22) { |
633 | /* rv = */ rounded_quotient(dval(&rv), tens[-e])(&rv)->d /= __tens_D2A[-e]; |
634 | if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) { |
635 | if (irv == STRTOG_NoMemory) |
636 | return (STRTOG_NoMemory); |
637 | goto ret; |
638 | } |
639 | e1 -= e; |
640 | } |
641 | #endif |
642 | } |
643 | rv_notOK: |
644 | e1 += nd - k; |
645 | |
646 | /* Get starting approximation = rv * 10**e1 */ |
647 | |
648 | e2 = 0; |
649 | if (e1 > 0) { |
650 | if ( (i = e1 & 15) !=0) |
651 | dval(&rv)(&rv)->d *= tens__tens_D2A[i]; |
652 | if (e1 &= ~15) { |
653 | e1 >>= 4; |
654 | while(e1 >= (1 << (n_bigtens5-1))) { |
655 | e2 += ((word0(&rv)(&rv)->L[1] & Exp_mask0x7ff00000) |
656 | >> Exp_shift120) - Bias1023; |
657 | word0(&rv)(&rv)->L[1] &= ~Exp_mask0x7ff00000; |
658 | word0(&rv)(&rv)->L[1] |= Bias1023 << Exp_shift120; |
659 | dval(&rv)(&rv)->d *= bigtens__bigtens_D2A[n_bigtens5-1]; |
660 | e1 -= 1 << (n_bigtens5-1); |
661 | } |
662 | e2 += ((word0(&rv)(&rv)->L[1] & Exp_mask0x7ff00000) >> Exp_shift120) - Bias1023; |
663 | word0(&rv)(&rv)->L[1] &= ~Exp_mask0x7ff00000; |
664 | word0(&rv)(&rv)->L[1] |= Bias1023 << Exp_shift120; |
665 | for(j = 0; e1 > 0; j++, e1 >>= 1) |
666 | if (e1 & 1) |
667 | dval(&rv)(&rv)->d *= bigtens__bigtens_D2A[j]; |
668 | } |
669 | } |
670 | else if (e1 < 0) { |
671 | e1 = -e1; |
672 | if ( (i = e1 & 15) !=0) |
673 | dval(&rv)(&rv)->d /= tens__tens_D2A[i]; |
674 | if (e1 &= ~15) { |
675 | e1 >>= 4; |
676 | while(e1 >= (1 << (n_bigtens5-1))) { |
677 | e2 += ((word0(&rv)(&rv)->L[1] & Exp_mask0x7ff00000) |
678 | >> Exp_shift120) - Bias1023; |
679 | word0(&rv)(&rv)->L[1] &= ~Exp_mask0x7ff00000; |
680 | word0(&rv)(&rv)->L[1] |= Bias1023 << Exp_shift120; |
681 | dval(&rv)(&rv)->d *= tinytens__tinytens_D2A[n_bigtens5-1]; |
682 | e1 -= 1 << (n_bigtens5-1); |
683 | } |
684 | e2 += ((word0(&rv)(&rv)->L[1] & Exp_mask0x7ff00000) >> Exp_shift120) - Bias1023; |
685 | word0(&rv)(&rv)->L[1] &= ~Exp_mask0x7ff00000; |
686 | word0(&rv)(&rv)->L[1] |= Bias1023 << Exp_shift120; |
687 | for(j = 0; e1 > 0; j++, e1 >>= 1) |
688 | if (e1 & 1) |
689 | dval(&rv)(&rv)->d *= tinytens__tinytens_D2A[j]; |
690 | } |
691 | } |
692 | #ifdef IBM |
693 | /* e2 is a correction to the (base 2) exponent of the return |
694 | * value, reflecting adjustments above to avoid overflow in the |
695 | * native arithmetic. For native IBM (base 16) arithmetic, we |
696 | * must multiply e2 by 4 to change from base 16 to 2. |
697 | */ |
698 | e2 <<= 2; |
699 | #endif |
700 | rvb = d2b__d2b_D2A(dval(&rv)(&rv)->d, &rve, &rvbits); /* rv = rvb * 2^rve */ |
701 | if (rvb == NULL((void *)0)) |
702 | return (STRTOG_NoMemory); |
703 | rve += e2; |
704 | if ((j = rvbits - nbits) > 0) { |
705 | rshift__rshift_D2A(rvb, j); |
706 | rvbits = nbits; |
707 | rve += j; |
708 | } |
709 | bb0 = 0; /* trailing zero bits in rvb */ |
710 | e2 = rve + rvbits - nbits; |
711 | if (e2 > fpi->emax + 1) |
712 | goto huge; |
713 | rve1 = rve + rvbits - nbits; |
714 | if (e2 < (emin = fpi->emin)) { |
715 | denorm = 1; |
716 | j = rve - emin; |
717 | if (j > 0) { |
718 | rvb = lshift__lshift_D2A(rvb, j); |
719 | if (rvb == NULL((void *)0)) |
720 | return (STRTOG_NoMemory); |
721 | rvbits += j; |
722 | } |
723 | else if (j < 0) { |
724 | rvbits += j; |
725 | if (rvbits <= 0) { |
726 | if (rvbits < -1) { |
727 | ufl: |
728 | rvb->wds = 0; |
729 | rvb->x[0] = 0; |
730 | *exp = emin; |
731 | irv = STRTOG_Underflow | STRTOG_Inexlo; |
732 | goto ret; |
733 | } |
734 | rvb->x[0] = rvb->wds = rvbits = 1; |
735 | } |
736 | else |
737 | rshift__rshift_D2A(rvb, -j); |
738 | } |
739 | rve = rve1 = emin; |
740 | if (sudden_underflow && e2 + 1 < emin) |
741 | goto ufl; |
742 | } |
743 | |
744 | /* Now the hard part -- adjusting rv to the correct value.*/ |
745 | |
746 | /* Put digits into bd: true value = bd * 10^e */ |
747 | |
748 | bd0 = s2b__s2b_D2A(s0, nd0, nd, y, dplen); |
749 | if (bd0 == NULL((void *)0)) |
750 | return (STRTOG_NoMemory); |
751 | |
752 | for(;;) { |
753 | bd = Balloc__Balloc_D2A(bd0->k); |
754 | if (bd == NULL((void *)0)) |
755 | return (STRTOG_NoMemory); |
756 | Bcopy(bd, bd0)memcpy(&bd->sign,&bd0->sign,bd0->wds*sizeof( ULong) + 2*sizeof(int)); |
757 | bb = Balloc__Balloc_D2A(rvb->k); |
758 | if (bb == NULL((void *)0)) |
759 | return (STRTOG_NoMemory); |
760 | Bcopy(bb, rvb)memcpy(&bb->sign,&rvb->sign,rvb->wds*sizeof( ULong) + 2*sizeof(int)); |
761 | bbbits = rvbits - bb0; |
762 | bbe = rve + bb0; |
763 | bs = i2b__i2b_D2A(1); |
764 | if (bs == NULL((void *)0)) |
765 | return (STRTOG_NoMemory); |
766 | |
767 | if (e >= 0) { |
768 | bb2 = bb5 = 0; |
769 | bd2 = bd5 = e; |
770 | } |
771 | else { |
772 | bb2 = bb5 = -e; |
773 | bd2 = bd5 = 0; |
774 | } |
775 | if (bbe >= 0) |
776 | bb2 += bbe; |
777 | else |
778 | bd2 -= bbe; |
779 | bs2 = bb2; |
780 | j = nbits + 1 - bbbits; |
781 | i = bbe + bbbits - nbits; |
782 | if (i < emin) /* denormal */ |
783 | j += i - emin; |
784 | bb2 += j; |
785 | bd2 += j; |
786 | i = bb2 < bd2 ? bb2 : bd2; |
787 | if (i > bs2) |
788 | i = bs2; |
789 | if (i > 0) { |
790 | bb2 -= i; |
791 | bd2 -= i; |
792 | bs2 -= i; |
793 | } |
794 | if (bb5 > 0) { |
795 | bs = pow5mult__pow5mult_D2A(bs, bb5); |
796 | if (bs == NULL((void *)0)) |
797 | return (STRTOG_NoMemory); |
798 | bb1 = mult__mult_D2A(bs, bb); |
799 | if (bb1 == NULL((void *)0)) |
800 | return (STRTOG_NoMemory); |
801 | Bfree__Bfree_D2A(bb); |
802 | bb = bb1; |
803 | } |
804 | bb2 -= bb0; |
805 | if (bb2 > 0) { |
806 | bb = lshift__lshift_D2A(bb, bb2); |
807 | if (bb == NULL((void *)0)) |
808 | return (STRTOG_NoMemory); |
809 | } |
810 | else if (bb2 < 0) |
811 | rshift__rshift_D2A(bb, -bb2); |
812 | if (bd5 > 0) { |
813 | bd = pow5mult__pow5mult_D2A(bd, bd5); |
814 | if (bd == NULL((void *)0)) |
815 | return (STRTOG_NoMemory); |
816 | } |
817 | if (bd2 > 0) { |
818 | bd = lshift__lshift_D2A(bd, bd2); |
819 | if (bd == NULL((void *)0)) |
820 | return (STRTOG_NoMemory); |
821 | } |
822 | if (bs2 > 0) { |
823 | bs = lshift__lshift_D2A(bs, bs2); |
824 | if (bs == NULL((void *)0)) |
825 | return (STRTOG_NoMemory); |
826 | } |
827 | asub = 1; |
828 | inex = STRTOG_Inexhi; |
829 | delta = diff__diff_D2A(bb, bd); |
830 | if (delta == NULL((void *)0)) |
831 | return (STRTOG_NoMemory); |
832 | if (delta->wds <= 1 && !delta->x[0]) |
833 | break; |
834 | dsign = delta->sign; |
835 | delta->sign = finished = 0; |
836 | L = 0; |
837 | i = cmp__cmp_D2A(delta, bs); |
838 | if (rd && i <= 0) { |
839 | irv = STRTOG_Normal; |
840 | if ( (finished = dsign ^ (rd&1)) !=0) { |
841 | if (dsign != 0) { |
842 | irv |= STRTOG_Inexhi; |
843 | goto adj1; |
844 | } |
845 | irv |= STRTOG_Inexlo; |
846 | if (rve1 == emin) |
847 | goto adj1; |
848 | for(i = 0, j = nbits; j >= ULbits32; |
849 | i++, j -= ULbits32) { |
850 | if (rvb->x[i] & ALL_ON0xffffffff) |
851 | goto adj1; |
852 | } |
853 | if (j > 1 && lo0bits__lo0bits_D2A(rvb->x + i) < j - 1) |
854 | goto adj1; |
855 | rve = rve1 - 1; |
856 | rvb = set_ones__set_ones_D2A(rvb, rvbits = nbits); |
857 | if (rvb == NULL((void *)0)) |
858 | return (STRTOG_NoMemory); |
859 | break; |
860 | } |
861 | irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi; |
862 | break; |
863 | } |
864 | if (i < 0) { |
865 | /* Error is less than half an ulp -- check for |
866 | * special case of mantissa a power of two. |
867 | */ |
868 | irv = dsign |
869 | ? STRTOG_Normal | STRTOG_Inexlo |
870 | : STRTOG_Normal | STRTOG_Inexhi; |
871 | if (dsign || bbbits > 1 || denorm || rve1 == emin) |
872 | break; |
873 | delta = lshift__lshift_D2A(delta,1); |
874 | if (delta == NULL((void *)0)) |
875 | return (STRTOG_NoMemory); |
876 | if (cmp__cmp_D2A(delta, bs) > 0) { |
877 | irv = STRTOG_Normal | STRTOG_Inexlo; |
878 | goto drop_down; |
879 | } |
880 | break; |
881 | } |
882 | if (i == 0) { |
883 | /* exactly half-way between */ |
884 | if (dsign) { |
885 | if (denorm && all_on(rvb, rvbits)) { |
886 | /*boundary case -- increment exponent*/ |
887 | rvb->wds = 1; |
888 | rvb->x[0] = 1; |
889 | rve = emin + nbits - (rvbits = 1); |
890 | irv = STRTOG_Normal | STRTOG_Inexhi; |
891 | denorm = 0; |
892 | break; |
893 | } |
894 | irv = STRTOG_Normal | STRTOG_Inexlo; |
895 | } |
896 | else if (bbbits == 1) { |
897 | irv = STRTOG_Normal; |
898 | drop_down: |
899 | /* boundary case -- decrement exponent */ |
900 | if (rve1 == emin) { |
901 | irv = STRTOG_Normal | STRTOG_Inexhi; |
902 | if (rvb->wds == 1 && rvb->x[0] == 1) |
903 | sudden_underflow = 1; |
904 | break; |
905 | } |
906 | rve -= nbits; |
907 | rvb = set_ones__set_ones_D2A(rvb, rvbits = nbits); |
908 | if (rvb == NULL((void *)0)) |
909 | return (STRTOG_NoMemory); |
910 | break; |
911 | } |
912 | else |
913 | irv = STRTOG_Normal | STRTOG_Inexhi; |
914 | if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1)) |
915 | break; |
916 | if (dsign) { |
917 | rvb = increment__increment_D2A(rvb); |
918 | if (rvb == NULL((void *)0)) |
919 | return (STRTOG_NoMemory); |
920 | j = kmask31 & (ULbits32 - (rvbits & kmask31)); |
921 | if (hi0bits(rvb->x[rvb->wds - 1])__hi0bits_D2A((ULong)(rvb->x[rvb->wds - 1])) != j) |
922 | rvbits++; |
923 | irv = STRTOG_Normal | STRTOG_Inexhi; |
924 | } |
925 | else { |
926 | if (bbbits == 1) |
927 | goto undfl; |
928 | decrement__decrement_D2A(rvb); |
929 | irv = STRTOG_Normal | STRTOG_Inexlo; |
930 | } |
931 | break; |
932 | } |
933 | if ((dval(&adj)(&adj)->d = ratio__ratio_D2A(delta, bs)) <= 2.) { |
934 | adj1: |
935 | inex = STRTOG_Inexlo; |
936 | if (dsign) { |
937 | asub = 0; |
938 | inex = STRTOG_Inexhi; |
939 | } |
940 | else if (denorm && bbbits <= 1) { |
941 | undfl: |
942 | rvb->wds = 0; |
943 | rve = emin; |
944 | irv = STRTOG_Underflow | STRTOG_Inexlo; |
945 | break; |
946 | } |
947 | adj0 = dval(&adj)(&adj)->d = 1.; |
948 | } |
949 | else { |
950 | adj0 = dval(&adj)(&adj)->d *= 0.5; |
951 | if (dsign) { |
952 | asub = 0; |
953 | inex = STRTOG_Inexlo; |
954 | } |
955 | if (dval(&adj)(&adj)->d < 2147483647.) { |
956 | L = adj0; |
957 | adj0 -= L; |
958 | switch(rd) { |
959 | case 0: |
960 | if (adj0 >= .5) |
961 | goto inc_L; |
962 | break; |
963 | case 1: |
964 | if (asub && adj0 > 0.) |
965 | goto inc_L; |
966 | break; |
967 | case 2: |
968 | if (!asub && adj0 > 0.) { |
969 | inc_L: |
970 | L++; |
971 | inex = STRTOG_Inexact - inex; |
972 | } |
973 | } |
974 | dval(&adj)(&adj)->d = L; |
975 | } |
976 | } |
977 | y = rve + rvbits; |
978 | |
979 | /* adj *= ulp(dval(&rv)); */ |
980 | /* if (asub) rv -= adj; else rv += adj; */ |
981 | |
982 | if (!denorm && rvbits < nbits) { |
983 | rvb = lshift__lshift_D2A(rvb, j = nbits - rvbits); |
984 | if (rvb == NULL((void *)0)) |
985 | return (STRTOG_NoMemory); |
986 | rve -= j; |
987 | rvbits = nbits; |
988 | } |
989 | ab = d2b__d2b_D2A(dval(&adj)(&adj)->d, &abe, &abits); |
990 | if (ab == NULL((void *)0)) |
991 | return (STRTOG_NoMemory); |
992 | if (abe < 0) |
993 | rshift__rshift_D2A(ab, -abe); |
994 | else if (abe > 0) { |
995 | ab = lshift__lshift_D2A(ab, abe); |
996 | if (ab == NULL((void *)0)) |
997 | return (STRTOG_NoMemory); |
998 | } |
999 | rvb0 = rvb; |
1000 | if (asub) { |
1001 | /* rv -= adj; */ |
1002 | j = hi0bits(rvb->x[rvb->wds-1])__hi0bits_D2A((ULong)(rvb->x[rvb->wds-1])); |
Value stored to 'j' is never read | |
1003 | rvb = diff__diff_D2A(rvb, ab); |
1004 | if (rvb == NULL((void *)0)) |
1005 | return (STRTOG_NoMemory); |
1006 | k = rvb0->wds - 1; |
1007 | if (denorm) |
1008 | /* do nothing */; |
1009 | else if (rvb->wds <= k |
1010 | || hi0bits( rvb->x[k])__hi0bits_D2A((ULong)(rvb->x[k])) > |
1011 | hi0bits(rvb0->x[k])__hi0bits_D2A((ULong)(rvb0->x[k]))) { |
1012 | /* unlikely; can only have lost 1 high bit */ |
1013 | if (rve1 == emin) { |
1014 | --rvbits; |
1015 | denorm = 1; |
1016 | } |
1017 | else { |
1018 | rvb = lshift__lshift_D2A(rvb, 1); |
1019 | if (rvb == NULL((void *)0)) |
1020 | return (STRTOG_NoMemory); |
1021 | --rve; |
1022 | --rve1; |
1023 | L = finished = 0; |
1024 | } |
1025 | } |
1026 | } |
1027 | else { |
1028 | rvb = sum__sum_D2A(rvb, ab); |
1029 | if (rvb == NULL((void *)0)) |
1030 | return (STRTOG_NoMemory); |
1031 | k = rvb->wds - 1; |
1032 | if (k >= rvb0->wds |
1033 | || hi0bits(rvb->x[k])__hi0bits_D2A((ULong)(rvb->x[k])) < hi0bits(rvb0->x[k])__hi0bits_D2A((ULong)(rvb0->x[k]))) { |
1034 | if (denorm) { |
1035 | if (++rvbits == nbits) |
1036 | denorm = 0; |
1037 | } |
1038 | else { |
1039 | rshift__rshift_D2A(rvb, 1); |
1040 | rve++; |
1041 | rve1++; |
1042 | L = 0; |
1043 | } |
1044 | } |
1045 | } |
1046 | Bfree__Bfree_D2A(ab); |
1047 | Bfree__Bfree_D2A(rvb0); |
1048 | if (finished) |
1049 | break; |
1050 | |
1051 | z = rve + rvbits; |
1052 | if (y == z && L) { |
1053 | /* Can we stop now? */ |
1054 | tol = dval(&adj)(&adj)->d * 5e-16; /* > max rel error */ |
1055 | dval(&adj)(&adj)->d = adj0 - .5; |
1056 | if (dval(&adj)(&adj)->d < -tol) { |
1057 | if (adj0 > tol) { |
1058 | irv |= inex; |
1059 | break; |
1060 | } |
1061 | } |
1062 | else if (dval(&adj)(&adj)->d > tol && adj0 < 1. - tol) { |
1063 | irv |= inex; |
1064 | break; |
1065 | } |
1066 | } |
1067 | bb0 = denorm ? 0 : trailz__trailz_D2A(rvb); |
1068 | Bfree__Bfree_D2A(bb); |
1069 | Bfree__Bfree_D2A(bd); |
1070 | Bfree__Bfree_D2A(bs); |
1071 | Bfree__Bfree_D2A(delta); |
1072 | } |
1073 | if (!denorm && (j = nbits - rvbits)) { |
1074 | if (j > 0) { |
1075 | rvb = lshift__lshift_D2A(rvb, j); |
1076 | if (rvb == NULL((void *)0)) |
1077 | return (STRTOG_NoMemory); |
1078 | } |
1079 | else |
1080 | rshift__rshift_D2A(rvb, -j); |
1081 | rve -= j; |
1082 | } |
1083 | *exp = rve; |
1084 | Bfree__Bfree_D2A(bb); |
1085 | Bfree__Bfree_D2A(bd); |
1086 | Bfree__Bfree_D2A(bs); |
1087 | Bfree__Bfree_D2A(bd0); |
1088 | Bfree__Bfree_D2A(delta); |
1089 | if (rve > fpi->emax) { |
1090 | switch(fpi->rounding & 3) { |
1091 | case FPI_Round_near: |
1092 | goto huge; |
1093 | case FPI_Round_up: |
1094 | if (!sign) |
1095 | goto huge; |
1096 | break; |
1097 | case FPI_Round_down: |
1098 | if (sign) |
1099 | goto huge; |
1100 | } |
1101 | /* Round to largest representable magnitude */ |
1102 | Bfree__Bfree_D2A(rvb); |
1103 | rvb = 0; |
1104 | irv = STRTOG_Normal | STRTOG_Inexlo; |
1105 | *exp = fpi->emax; |
1106 | b = bits; |
1107 | be = b + ((fpi->nbits + 31) >> 5); |
1108 | while(b < be) |
1109 | *b++ = -1; |
1110 | if ((j = fpi->nbits & 0x1f)) |
1111 | *--be >>= (32 - j); |
1112 | goto ret; |
1113 | huge: |
1114 | rvb->wds = 0; |
1115 | irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; |
1116 | #ifndef NO_ERRNO |
1117 | errno(*__errno()) = ERANGE34; |
1118 | #endif |
1119 | infnanexp: |
1120 | *exp = fpi->emax + 1; |
1121 | } |
1122 | ret: |
1123 | if (denorm) { |
1124 | if (sudden_underflow) { |
1125 | rvb->wds = 0; |
1126 | irv = STRTOG_Underflow | STRTOG_Inexlo; |
1127 | #ifndef NO_ERRNO |
1128 | errno(*__errno()) = ERANGE34; |
1129 | #endif |
1130 | } |
1131 | else { |
1132 | irv = (irv & ~STRTOG_Retmask) | |
1133 | (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero); |
1134 | if (irv & STRTOG_Inexact) { |
1135 | irv |= STRTOG_Underflow; |
1136 | #ifndef NO_ERRNO |
1137 | errno(*__errno()) = ERANGE34; |
1138 | #endif |
1139 | } |
1140 | } |
1141 | } |
1142 | if (se) |
1143 | *se = (char *)s; |
1144 | if (sign) |
1145 | irv |= STRTOG_Neg; |
1146 | if (rvb) { |
1147 | copybits__copybits_D2A(bits, nbits, rvb); |
1148 | Bfree__Bfree_D2A(rvb); |
1149 | } |
1150 | return irv; |
1151 | } |