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