master
1/****************************************************************
2
3The author of this software is David M. Gay.
4
5Copyright (C) 1998-2001 by Lucent Technologies
6All Rights Reserved
7
8Permission to use, copy, modify, and distribute this software and
9its documentation for any purpose and without fee is hereby
10granted, provided that the above copyright notice appear in all
11copies and that both that the copyright notice and this
12permission notice and warranty disclaimer appear in supporting
13documentation, and that the name of Lucent or any of its entities
14not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
17
18LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25THIS 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_LOCALE
35#include "locale.h"
36#endif
37
38static const int
39fivesbits[] = { 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};
43
44Bigint *increment (Bigint *b)
45{
46 ULong *x, *xe;
47 Bigint *b1;
48#ifdef Pack_16
49 ULong carry = 1, y;
50#endif
51
52 x = b->x;
53 xe = x + b->wds;
54#ifdef Pack_32
55 do {
56 if (*x < (ULong)0xffffffffL) {
57 ++*x;
58 return b;
59 }
60 *x++ = 0;
61 } while(x < xe);
62#else
63 do {
64 y = *x + carry;
65 carry = y >> 16;
66 *x++ = y & 0xffff;
67 if (!carry)
68 return b;
69 } while(x < xe);
70 if (carry)
71#endif
72 {
73 if (b->wds >= b->maxwds) {
74 b1 = Balloc(b->k+1);
75 Bcopy(b1,b);
76 Bfree(b);
77 b = b1;
78 }
79 b->x[b->wds++] = 1;
80 }
81 return b;
82}
83
84void decrement (Bigint *b)
85{
86 ULong *x, *xe;
87#ifdef Pack_16
88 ULong borrow = 1, y;
89#endif
90
91 x = b->x;
92 xe = x + b->wds;
93#ifdef Pack_32
94 do {
95 if (*x) {
96 --*x;
97 break;
98 }
99 *x++ = 0xffffffffL;
100 } while(x < xe);
101#else
102 do {
103 y = *x - borrow;
104 borrow = (y & 0x10000) >> 16;
105 *x++ = y & 0xffff;
106 } while(borrow && x < xe);
107#endif
108}
109
110static int all_on (Bigint *b, int n)
111{
112 ULong *x, *xe;
113
114 x = b->x;
115 xe = x + (n >> kshift);
116 while(x < xe)
117 if ((*x++ & ALL_ON) != ALL_ON)
118 return 0;
119 if (n &= kmask)
120 return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON;
121 return 1;
122}
123
124Bigint *set_ones (Bigint *b, int n)
125{
126 int k;
127 ULong *x, *xe;
128
129 k = (n + ((1 << kshift) - 1)) >> kshift;
130 if (b->k < k) {
131 Bfree(b);
132 b = Balloc(k);
133 }
134 k = n >> kshift;
135 if (n &= kmask)
136 k++;
137 b->wds = k;
138 x = b->x;
139 xe = x + k;
140 while(x < xe)
141 *x++ = ALL_ON;
142 if (n)
143 x[-1] >>= ULbits - n;
144 return b;
145}
146
147static int rvOK (dbl_union *d, FPI *fpi, Long *expo, ULong *bits,
148 int exact, int rd, int *irv)
149{
150 Bigint *b;
151 ULong carry, inex, lostbits;
152 int bdif, e, j, k, k1, nb, rv;
153
154 carry = rv = 0;
155 b = d2b(dval(d), &e, &bdif);
156 bdif -= nb = fpi->nbits;
157 e += bdif;
158 if (bdif <= 0) {
159 if (exact)
160 goto trunc;
161 goto ret;
162 }
163 if (P == nb) {
164 if (
165#ifndef IMPRECISE_INEXACT
166 exact &&
167#endif
168 fpi->rounding ==
169#ifdef RND_PRODQUOT
170 FPI_Round_near
171#else
172 Flt_Rounds
173#endif
174 ) goto trunc;
175 goto ret;
176 }
177 switch(rd) {
178 case 1: /* round down (toward -Infinity) */
179 goto trunc;
180 case 2: /* round up (toward +Infinity) */
181 break;
182 default: /* round near */
183 k = bdif - 1;
184 if (k < 0)
185 goto trunc;
186 if (!k) {
187 if (!exact)
188 goto ret;
189 if (b->x[0] & 2)
190 break;
191 goto trunc;
192 }
193 if (b->x[k>>kshift] & ((ULong)1 << (k & kmask)))
194 break;
195 goto trunc;
196 }
197 /* "break" cases: round up 1 bit, then truncate; bdif > 0 */
198 carry = 1;
199 trunc:
200 inex = lostbits = 0;
201 if (bdif > 0) {
202 if ( (lostbits = any_on(b, bdif)) !=0)
203 inex = STRTOG_Inexlo;
204 rshift(b, bdif);
205 if (carry) {
206 inex = STRTOG_Inexhi;
207 b = increment(b);
208 if ( (j = nb & kmask) !=0)
209 j = ULbits - j;
210 if (hi0bits(b->x[b->wds - 1]) != j) {
211 if (!lostbits)
212 lostbits = b->x[0] & 1;
213 rshift(b, 1);
214 e++;
215 }
216 }
217 }
218 else if (bdif < 0)
219 b = lshift(b, -bdif);
220 if (e < fpi->emin) {
221 k = fpi->emin - e;
222 e = fpi->emin;
223 if (k > nb || fpi->sudden_underflow) {
224 b->wds = inex = 0;
225 *irv = STRTOG_Underflow | STRTOG_Inexlo;
226 }
227 else {
228 k1 = k - 1;
229 if (k1 > 0 && !lostbits)
230 lostbits = any_on(b, k1);
231 if (!lostbits && !exact)
232 goto ret;
233 lostbits |=
234 carry = b->x[k1>>kshift] & (1 << (k1 & kmask));
235 rshift(b, k);
236 *irv = STRTOG_Denormal;
237 if (carry) {
238 b = increment(b);
239 inex = STRTOG_Inexhi | STRTOG_Underflow;
240 }
241 else if (lostbits)
242 inex = STRTOG_Inexlo | STRTOG_Underflow;
243 }
244 }
245 else if (e > fpi->emax) {
246 e = fpi->emax + 1;
247 *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
248 SET_ERRNO(ERANGE);
249 b->wds = inex = 0;
250 }
251 *expo = e;
252 copybits(bits, nb, b);
253 *irv |= inex;
254 rv = 1;
255 ret:
256 Bfree(b);
257 return rv;
258}
259
260static int mantbits (dbl_union *d)
261{
262 ULong L;
263 if ( (L = word1(d)) !=0)
264 return P - lo0bits(&L);
265 L = word0(d) | Exp_msk1;
266 return P - 32 - lo0bits(&L);
267}
268
269int __strtodg (const char *s00, char **se, FPI *fpi, Long *expo, ULong *bits)
270{
271 int abe, abits, asub;
272 int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm;
273 int dsign, e, e1, e2, emin, esign, finished, i, inex, irv, j, k;
274 int nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign;
275 int sudden_underflow;
276 const char *s, *s0, *s1;
277 double adj0, tol;
278 Long L;
279 union _dbl_union adj, rv;
280 ULong *b, *be, y, z;
281 Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
282#ifdef USE_LOCALE /*{{*/
283#ifdef NO_LOCALE_CACHE
284 char *decimalpoint = localeconv()->decimal_point;
285 int dplen = strlen(decimalpoint);
286#else
287 char *decimalpoint;
288 static char *decimalpoint_cache;
289 static int dplen;
290 if (!(s0 = decimalpoint_cache)) {
291 s0 = localeconv()->decimal_point;
292 if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
293 strcpy(decimalpoint_cache, s0);
294 s0 = decimalpoint_cache;
295 }
296 dplen = strlen(s0);
297 }
298 decimalpoint = (char*)s0;
299#endif /*NO_LOCALE_CACHE*/
300#else /*USE_LOCALE}{*/
301#define dplen 1
302#endif /*USE_LOCALE}}*/
303
304 irv = STRTOG_Zero;
305 denorm = sign = nz0 = nz = 0;
306 dval(&rv) = 0.;
307 rvb = 0;
308 nbits = fpi->nbits;
309 for(s = s00;;s++) switch(*s) {
310 case '-':
311 sign = 1;
312 /* fallthrough */
313 case '+':
314 if (*++s)
315 goto break2;
316 /* fallthrough */
317 case 0:
318 sign = 0;
319 irv = STRTOG_NoNumber;
320 s = s00;
321 goto ret;
322 case '\t':
323 case '\n':
324 case '\v':
325 case '\f':
326 case '\r':
327 case ' ':
328 continue;
329 default:
330 goto break2;
331 }
332 break2:
333 if (*s == '0') {
334#ifndef NO_HEX_FP
335 switch(s[1]) {
336 case 'x':
337 case 'X':
338 irv = gethex(&s, fpi, expo, &rvb, sign);
339 if (irv == STRTOG_NoNumber) {
340 s = s00;
341 sign = 0;
342 }
343 goto ret;
344 }
345#endif
346 nz0 = 1;
347 while(*++s == '0') ;
348 if (!*s)
349 goto ret;
350 }
351 sudden_underflow = fpi->sudden_underflow;
352 s0 = s;
353 y = z = 0;
354 for(decpt = nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
355 if (nd < 9)
356 y = 10*y + c - '0';
357 else if (nd < 16)
358 z = 10*z + c - '0';
359 nd0 = nd;
360#ifdef USE_LOCALE
361 if (c == *decimalpoint) {
362 for(i = 1; decimalpoint[i]; ++i)
363 if (s[i] != decimalpoint[i])
364 goto dig_done;
365 s += i;
366 c = *s;
367#else
368 if (c == '.') {
369 c = *++s;
370#endif
371 decpt = 1;
372 if (!nd) {
373 for(; c == '0'; c = *++s)
374 nz++;
375 if (c > '0' && c <= '9') {
376 s0 = s;
377 nf += nz;
378 nz = 0;
379 goto have_dig;
380 }
381 goto dig_done;
382 }
383 for(; c >= '0' && c <= '9'; c = *++s) {
384 have_dig:
385 nz++;
386 if (c -= '0') {
387 nf += nz;
388 for(i = 1; i < nz; i++)
389 if (nd++ < 9)
390 y *= 10;
391 else if (nd <= DBL_DIG + 1)
392 z *= 10;
393 if (nd++ < 9)
394 y = 10*y + c;
395 else if (nd <= DBL_DIG + 1)
396 z = 10*z + c;
397 nz = 0;
398 }
399 }
400 }/*}*/
401 dig_done:
402 e = 0;
403 if (c == 'e' || c == 'E') {
404 if (!nd && !nz && !nz0) {
405 irv = STRTOG_NoNumber;
406 s = s00;
407 goto ret;
408 }
409 s00 = s;
410 esign = 0;
411 switch(c = *++s) {
412 case '-':
413 esign = 1;
414 /* fallthrough */
415 case '+':
416 c = *++s;
417 /* fallthrough */
418 }
419 if (c >= '0' && c <= '9') {
420 while(c == '0')
421 c = *++s;
422 if (c > '0' && c <= '9') {
423 L = c - '0';
424 s1 = s;
425 while((c = *++s) >= '0' && c <= '9')
426 L = 10*L + c - '0';
427 if (s - s1 > 8 || L > 19999)
428 /* Avoid confusion from exponents
429 * so large that e might overflow.
430 */
431 e = 19999; /* safe for 16 bit ints */
432 else
433 e = (int)L;
434 if (esign)
435 e = -e;
436 }
437 else
438 e = 0;
439 }
440 else
441 s = s00;
442 }
443 if (!nd) {
444 if (!nz && !nz0) {
445#ifdef INFNAN_CHECK
446 /* Check for Nan and Infinity */
447 if (!decpt)
448 switch(c) {
449 case 'i':
450 case 'I':
451 if (match(&s,"nf")) {
452 --s;
453 if (!match(&s,"inity"))
454 ++s;
455 irv = STRTOG_Infinite;
456 goto infnanexp;
457 }
458 break;
459 case 'n':
460 case 'N':
461 if (match(&s, "an")) {
462 irv = STRTOG_NaN;
463 *expo = fpi->emax + 1;
464#ifndef No_Hex_NaN
465 if (*s == '(') /*)*/
466 irv = hexnan(&s, fpi, bits);
467#endif
468 goto infnanexp;
469 }
470 }
471#endif /* INFNAN_CHECK */
472 irv = STRTOG_NoNumber;
473 s = s00;
474 }
475 goto ret;
476 }
477
478 irv = STRTOG_Normal;
479 e1 = e -= nf;
480 rd = 0;
481 switch(fpi->rounding & 3) {
482 case FPI_Round_up:
483 rd = 2 - sign;
484 break;
485 case FPI_Round_zero:
486 rd = 1;
487 break;
488 case FPI_Round_down:
489 rd = 1 + sign;
490 }
491
492 /* Now we have nd0 digits, starting at s0, followed by a
493 * decimal point, followed by nd-nd0 digits. The number we're
494 * after is the integer represented by those digits times
495 * 10**e */
496
497 if (!nd0)
498 nd0 = nd;
499 k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2;
500 dval(&rv) = y;
501 if (k > 9)
502 dval(&rv) = tens[k - 9] * dval(&rv) + z;
503 bd0 = 0;
504 if (nbits <= P && nd <= DBL_DIG) {
505 if (!e) {
506 if (rvOK(&rv, fpi, expo, bits, 1, rd, &irv))
507 goto ret;
508 }
509 else if (e > 0) {
510 if (e <= Ten_pmax) {
511 i = fivesbits[e] + mantbits(&rv) <= P;
512 /* rv = */ rounded_product(dval(&rv), tens[e]);
513 if (rvOK(&rv, fpi, expo, bits, i, rd, &irv))
514 goto ret;
515 e1 -= e;
516 goto rv_notOK;
517 }
518 i = DBL_DIG - nd;
519 if (e <= Ten_pmax + i) {
520 /* A fancier test would sometimes let us do
521 * this for larger i values.
522 */
523 e2 = e - i;
524 e1 -= i;
525 dval(&rv) *= tens[i];
526 /* rv = */ rounded_product(dval(&rv), tens[e2]);
527 if (rvOK(&rv, fpi, expo, bits, 0, rd, &irv))
528 goto ret;
529 e1 -= e2;
530 }
531 }
532#ifndef Inaccurate_Divide
533 else if (e >= -Ten_pmax) {
534 /* rv = */ rounded_quotient(dval(&rv), tens[-e]);
535 if (rvOK(&rv, fpi, expo, bits, 0, rd, &irv))
536 goto ret;
537 e1 -= e;
538 }
539#endif
540 }
541 rv_notOK:
542 e1 += nd - k;
543
544 /* Get starting approximation = rv * 10**e1 */
545
546 e2 = 0;
547 if (e1 > 0) {
548 if ( (i = e1 & 15) !=0)
549 dval(&rv) *= tens[i];
550 if (e1 &= ~15) {
551 e1 >>= 4;
552 while(e1 >= (1 << (n_bigtens-1))) {
553 e2 += ((word0(&rv) & Exp_mask)
554 >> Exp_shift1) - Bias;
555 word0(&rv) &= ~Exp_mask;
556 word0(&rv) |= Bias << Exp_shift1;
557 dval(&rv) *= bigtens[n_bigtens-1];
558 e1 -= 1 << (n_bigtens-1);
559 }
560 e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias;
561 word0(&rv) &= ~Exp_mask;
562 word0(&rv) |= Bias << Exp_shift1;
563 for(j = 0; e1 > 0; j++, e1 >>= 1)
564 if (e1 & 1)
565 dval(&rv) *= bigtens[j];
566 }
567 }
568 else if (e1 < 0) {
569 e1 = -e1;
570 if ( (i = e1 & 15) !=0)
571 dval(&rv) /= tens[i];
572 if (e1 &= ~15) {
573 e1 >>= 4;
574 while(e1 >= (1 << (n_bigtens-1))) {
575 e2 += ((word0(&rv) & Exp_mask)
576 >> Exp_shift1) - Bias;
577 word0(&rv) &= ~Exp_mask;
578 word0(&rv) |= Bias << Exp_shift1;
579 dval(&rv) *= tinytens[n_bigtens-1];
580 e1 -= 1 << (n_bigtens-1);
581 }
582 e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias;
583 word0(&rv) &= ~Exp_mask;
584 word0(&rv) |= Bias << Exp_shift1;
585 for(j = 0; e1 > 0; j++, e1 >>= 1)
586 if (e1 & 1)
587 dval(&rv) *= tinytens[j];
588 }
589 }
590 rvb = d2b(dval(&rv), &rve, &rvbits); /* rv = rvb * 2^rve */
591 rve += e2;
592 if ((j = rvbits - nbits) > 0) {
593 rshift(rvb, j);
594 rvbits = nbits;
595 rve += j;
596 }
597 bb0 = 0; /* trailing zero bits in rvb */
598 e2 = rve + rvbits - nbits;
599 if (e2 > fpi->emax + 1)
600 goto huge;
601 rve1 = rve + rvbits - nbits;
602 if (e2 < (emin = fpi->emin)) {
603 denorm = 1;
604 j = rve - emin;
605 if (j > 0) {
606 rvb = lshift(rvb, j);
607 rvbits += j;
608 }
609 else if (j < 0) {
610 rvbits += j;
611 if (rvbits <= 0) {
612 if (rvbits < -1) {
613 ufl:
614 rvb->wds = 0;
615 rvb->x[0] = 0;
616 *expo = emin;
617 irv = STRTOG_Underflow | STRTOG_Inexlo;
618 goto ret;
619 }
620 rvb->x[0] = rvb->wds = rvbits = 1;
621 }
622 else
623 rshift(rvb, -j);
624 }
625 rve = rve1 = emin;
626 if (sudden_underflow && e2 + 1 < emin)
627 goto ufl;
628 }
629
630 /* Now the hard part -- adjusting rv to the correct value.*/
631
632 /* Put digits into bd: true value = bd * 10^e */
633
634 bd0 = s2b(s0, nd0, nd, y, dplen);
635
636 for(;;) {
637 bd = Balloc(bd0->k);
638 Bcopy(bd, bd0);
639 bb = Balloc(rvb->k);
640 Bcopy(bb, rvb);
641 bbbits = rvbits - bb0;
642 bbe = rve + bb0;
643 bs = i2b(1);
644
645 if (e >= 0) {
646 bb2 = bb5 = 0;
647 bd2 = bd5 = e;
648 }
649 else {
650 bb2 = bb5 = -e;
651 bd2 = bd5 = 0;
652 }
653 if (bbe >= 0)
654 bb2 += bbe;
655 else
656 bd2 -= bbe;
657 bs2 = bb2;
658 j = nbits + 1 - bbbits;
659 i = bbe + bbbits - nbits;
660 if (i < emin) /* denormal */
661 j += i - emin;
662 bb2 += j;
663 bd2 += j;
664 i = bb2 < bd2 ? bb2 : bd2;
665 if (i > bs2)
666 i = bs2;
667 if (i > 0) {
668 bb2 -= i;
669 bd2 -= i;
670 bs2 -= i;
671 }
672 if (bb5 > 0) {
673 bs = pow5mult(bs, bb5);
674 bb1 = mult(bs, bb);
675 Bfree(bb);
676 bb = bb1;
677 }
678 bb2 -= bb0;
679 if (bb2 > 0)
680 bb = lshift(bb, bb2);
681 else if (bb2 < 0)
682 rshift(bb, -bb2);
683 if (bd5 > 0)
684 bd = pow5mult(bd, bd5);
685 if (bd2 > 0)
686 bd = lshift(bd, bd2);
687 if (bs2 > 0)
688 bs = lshift(bs, bs2);
689 asub = 1;
690 inex = STRTOG_Inexhi;
691 delta = diff(bb, bd);
692 if (delta->wds <= 1 && !delta->x[0])
693 break;
694 dsign = delta->sign;
695 delta->sign = finished = 0;
696 L = 0;
697 i = cmp(delta, bs);
698 if (rd && i <= 0) {
699 irv = STRTOG_Normal;
700 if ( (finished = dsign ^ (rd&1)) !=0) {
701 if (dsign != 0) {
702 irv |= STRTOG_Inexhi;
703 goto adj1;
704 }
705 irv |= STRTOG_Inexlo;
706 if (rve1 == emin)
707 goto adj1;
708 for(i = 0, j = nbits; j >= ULbits;
709 i++, j -= ULbits) {
710 if (rvb->x[i] & ALL_ON)
711 goto adj1;
712 }
713 if (j > 1 && lo0bits(rvb->x + i) < j - 1)
714 goto adj1;
715 rve = rve1 - 1;
716 rvb = set_ones(rvb, rvbits = nbits);
717 break;
718 }
719 irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi;
720 break;
721 }
722 if (i < 0) {
723 /* Error is less than half an ulp -- check for
724 * special case of mantissa a power of two.
725 */
726 irv = dsign
727 ? STRTOG_Normal | STRTOG_Inexlo
728 : STRTOG_Normal | STRTOG_Inexhi;
729 if (dsign || bbbits > 1 || denorm || rve1 == emin)
730 break;
731 delta = lshift(delta,1);
732 if (cmp(delta, bs) > 0) {
733 irv = STRTOG_Normal | STRTOG_Inexlo;
734 goto drop_down;
735 }
736 break;
737 }
738 if (i == 0) {
739 /* exactly half-way between */
740 if (dsign) {
741 if (denorm && all_on(rvb, rvbits)) {
742 /*boundary case -- increment exponent*/
743 rvb->wds = 1;
744 rvb->x[0] = 1;
745 rve = emin + nbits - (rvbits = 1);
746 irv = STRTOG_Normal | STRTOG_Inexhi;
747 denorm = 0;
748 break;
749 }
750 irv = STRTOG_Normal | STRTOG_Inexlo;
751 }
752 else if (bbbits == 1) {
753 irv = STRTOG_Normal;
754 drop_down:
755 /* boundary case -- decrement exponent */
756 if (rve1 == emin) {
757 irv = STRTOG_Normal | STRTOG_Inexhi;
758 if (rvb->wds == 1 && rvb->x[0] == 1)
759 sudden_underflow = 1;
760 break;
761 }
762 rve -= nbits;
763 rvb = set_ones(rvb, rvbits = nbits);
764 break;
765 }
766 else
767 irv = STRTOG_Normal | STRTOG_Inexhi;
768 if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1))
769 break;
770 if (dsign) {
771 rvb = increment(rvb);
772 j = kmask & (ULbits - (rvbits & kmask));
773 if (hi0bits(rvb->x[rvb->wds - 1]) != j)
774 rvbits++;
775 irv = STRTOG_Normal | STRTOG_Inexhi;
776 }
777 else {
778 if (bbbits == 1)
779 goto undfl;
780 decrement(rvb);
781 irv = STRTOG_Normal | STRTOG_Inexlo;
782 }
783 break;
784 }
785 if ((dval(&adj) = ratio(delta, bs)) <= 2.) {
786 adj1:
787 inex = STRTOG_Inexlo;
788 if (dsign) {
789 asub = 0;
790 inex = STRTOG_Inexhi;
791 }
792 else if (denorm && bbbits <= 1) {
793 undfl:
794 rvb->wds = 0;
795 rve = emin;
796 irv = STRTOG_Underflow | STRTOG_Inexlo;
797 break;
798 }
799 adj0 = dval(&adj) = 1.;
800 }
801 else {
802 adj0 = dval(&adj) *= 0.5;
803 if (dsign) {
804 asub = 0;
805 inex = STRTOG_Inexlo;
806 }
807 if (dval(&adj) < 2147483647.) {
808 L = adj0;
809 adj0 -= L;
810 switch(rd) {
811 case 0:
812 if (adj0 >= .5)
813 goto inc_L;
814 break;
815 case 1:
816 if (asub && adj0 > 0.)
817 goto inc_L;
818 break;
819 case 2:
820 if (!asub && adj0 > 0.) {
821 inc_L:
822 L++;
823 inex = STRTOG_Inexact - inex;
824 }
825 }
826 dval(&adj) = L;
827 }
828 }
829 y = rve + rvbits;
830
831 /* adj *= ulp(&rv); */
832 /* if (asub) rv -= adj; else rv += adj; */
833
834 if (!denorm && rvbits < nbits) {
835 rvb = lshift(rvb, j = nbits - rvbits);
836 rve -= j;
837 rvbits = nbits;
838 }
839 ab = d2b(dval(&adj), &abe, &abits);
840 if (abe < 0)
841 rshift(ab, -abe);
842 else if (abe > 0)
843 ab = lshift(ab, abe);
844 rvb0 = rvb;
845 if (asub) {
846 /* rv -= adj; */
847 j = hi0bits(rvb->x[rvb->wds-1]);
848 rvb = diff(rvb, ab);
849 k = rvb0->wds - 1;
850 if (denorm)
851 /* do nothing */;
852 else if (rvb->wds <= k
853 || hi0bits( rvb->x[k]) >
854 hi0bits(rvb0->x[k])) {
855 /* unlikely; can only have lost 1 high bit */
856 if (rve1 == emin) {
857 --rvbits;
858 denorm = 1;
859 }
860 else {
861 rvb = lshift(rvb, 1);
862 --rve;
863 --rve1;
864 L = finished = 0;
865 }
866 }
867 }
868 else {
869 rvb = sum(rvb, ab);
870 k = rvb->wds - 1;
871 if (k >= rvb0->wds
872 || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) {
873 if (denorm) {
874 if (++rvbits == nbits)
875 denorm = 0;
876 }
877 else {
878 rshift(rvb, 1);
879 rve++;
880 rve1++;
881 L = 0;
882 }
883 }
884 }
885 Bfree(ab);
886 Bfree(rvb0);
887 if (finished)
888 break;
889
890 z = rve + rvbits;
891 if (y == z && L) {
892 /* Can we stop now? */
893 tol = dval(&adj) * 5e-16; /* > max rel error */
894 dval(&adj) = adj0 - .5;
895 if (dval(&adj) < -tol) {
896 if (adj0 > tol) {
897 irv |= inex;
898 break;
899 }
900 }
901 else if (dval(&adj) > tol && adj0 < 1. - tol) {
902 irv |= inex;
903 break;
904 }
905 }
906 bb0 = denorm ? 0 : trailz(rvb);
907 Bfree(bb);
908 Bfree(bd);
909 Bfree(bs);
910 Bfree(delta);
911 }
912 if (!denorm && (j = nbits - rvbits)) {
913 if (j > 0)
914 rvb = lshift(rvb, j);
915 else
916 rshift(rvb, -j);
917 rve -= j;
918 }
919 *expo = rve;
920 Bfree(bb);
921 Bfree(bd);
922 Bfree(bs);
923 Bfree(bd0);
924 Bfree(delta);
925 if (rve > fpi->emax) {
926huge:
927 Bfree(rvb);
928 rvb = 0;
929 SET_ERRNO(ERANGE);
930 switch(fpi->rounding & 3) {
931 case FPI_Round_up:
932 if (!sign)
933 goto ret_inf;
934 break;
935 case FPI_Round_down:
936 if (!sign)
937 break;
938 /* fallthrough */
939 case FPI_Round_near:
940 ret_inf:
941 irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
942 k = nbits >> kshift;
943 if (nbits & kmask)
944 ++k;
945 memset(bits, 0, k*sizeof(ULong));
946 infnanexp:
947 *expo = fpi->emax + 1;
948 goto ret;
949 }
950 /* Round to largest representable magnitude */
951 irv = STRTOG_Normal | STRTOG_Inexlo;
952 *expo = fpi->emax;
953 b = bits;
954 be = b + ((fpi->nbits + 31) >> 5);
955 while(b < be)
956 *b++ = -1;
957 if ((j = fpi->nbits & 0x1f))
958 *--be >>= (32 - j);
959 }
960 ret:
961 if (denorm) {
962 if (sudden_underflow) {
963 rvb->wds = 0;
964 irv = STRTOG_Underflow | STRTOG_Inexlo;
965 SET_ERRNO(ERANGE);
966 }
967 else {
968 irv = (irv & ~STRTOG_Retmask) |
969 (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero);
970 if (irv & STRTOG_Inexact) {
971 irv |= STRTOG_Underflow;
972 SET_ERRNO(ERANGE);
973 }
974 }
975 }
976 if (se)
977 *se = (char *)s;
978 if (sign)
979 irv |= STRTOG_Neg;
980 if (rvb) {
981 copybits(bits, nbits, rvb);
982 Bfree(rvb);
983 }
984 return irv;
985}