Remove building with NOCRYPTO option
[minix3.git] / lib / libc / gdtoa / strtodg.c
blobd0a910594561f6c2ea82d46e4339948215cc0f74
1 /* $NetBSD: strtodg.c,v 1.12 2013/04/19 10:41:53 joerg Exp $ */
3 /****************************************************************
5 The author of this software is David M. Gay.
7 Copyright (C) 1998-2001 by Lucent Technologies
8 All Rights Reserved
10 Permission to use, copy, modify, and distribute this software and
11 its documentation for any purpose and without fee is hereby
12 granted, provided that the above copyright notice appear in all
13 copies and that both that the copyright notice and this
14 permission notice and warranty disclaimer appear in supporting
15 documentation, and that the name of Lucent or any of its entities
16 not be used in advertising or publicity pertaining to
17 distribution of the software without specific, written prior
18 permission.
20 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
22 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
23 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
25 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
27 THIS SOFTWARE.
29 ****************************************************************/
31 /* Please send bug reports to David M. Gay (dmg at acm dot org,
32 * with " at " changed at "@" and " dot " changed to "."). */
34 #include "gdtoaimp.h"
36 #ifdef USE_LOCALE
37 #include "locale.h"
38 #endif
40 #ifndef VAX
41 static CONST int
42 fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
43 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
44 47, 49, 52
46 #endif
48 Bigint *
49 #ifdef KR_headers
50 increment(b) Bigint *b;
51 #else
52 increment(Bigint *b)
53 #endif
55 ULong *x, *xe;
56 Bigint *b1;
57 #ifdef Pack_16
58 ULong carry = 1, y;
59 #endif
61 x = b->x;
62 xe = x + b->wds;
63 #ifdef Pack_32
64 do {
65 if (*x < (ULong)0xffffffffL) {
66 ++*x;
67 return b;
69 *x++ = 0;
70 } while(x < xe);
71 #else
72 do {
73 y = *x + carry;
74 carry = y >> 16;
75 *x++ = y & 0xffff;
76 if (!carry)
77 return b;
78 } while(x < xe);
79 if (carry)
80 #endif
82 if (b->wds >= b->maxwds) {
83 b1 = Balloc(b->k+1);
84 if (b1 == NULL)
85 return NULL;
86 Bcopy(b1,b);
87 Bfree(b);
88 b = b1;
90 b->x[b->wds++] = 1;
92 return b;
95 void
96 #ifdef KR_headers
97 decrement(b) Bigint *b;
98 #else
99 decrement(Bigint *b)
100 #endif
102 ULong *x, *xe;
103 #ifdef Pack_16
104 ULong borrow = 1, y;
105 #endif
107 x = b->x;
108 xe = x + b->wds;
109 #ifdef Pack_32
110 do {
111 if (*x) {
112 --*x;
113 break;
115 *x++ = 0xffffffffUL;
117 while(x < xe);
118 #else
119 do {
120 y = *x - borrow;
121 borrow = (y & 0x10000) >> 16;
122 *x++ = y & 0xffff;
123 } while(borrow && x < xe);
124 #endif
127 static int
128 #ifdef KR_headers
129 all_on(b, n) CONST Bigint *b; int n;
130 #else
131 all_on(CONST Bigint *b, int n)
132 #endif
134 CONST ULong *x, *xe;
136 x = b->x;
137 xe = x + ((unsigned int)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;
146 Bigint *
147 #ifdef KR_headers
148 set_ones(b, n) Bigint *b; int n;
149 #else
150 set_ones(Bigint *b, int n)
151 #endif
153 int k;
154 ULong *x, *xe;
156 k = (unsigned int)(n + ((1 << kshift) - 1)) >> kshift;
157 if (b->k < k) {
158 Bfree(b);
159 b = Balloc(k);
160 if (b == NULL)
161 return NULL;
163 k = (unsigned int)n >> kshift;
164 if (n &= kmask)
165 k++;
166 b->wds = k;
167 x = b->x;
168 xe = x + k;
169 while(x < xe)
170 *x++ = ALL_ON;
171 if (n)
172 x[-1] >>= ULbits - n;
173 return b;
176 static int
177 rvOK
178 #ifdef KR_headers
179 (d, fpi, expt, bits, exact, rd, irv)
180 U *d; CONST FPI *fpi; Long *expt; ULong *bits; int exact, rd, *irv;
181 #else
182 (U *d, CONST FPI *fpi, Long *expt, ULong *bits, int exact, int rd, int *irv)
183 #endif
185 Bigint *b;
186 ULong carry, inex, lostbits;
187 int bdif, e, j, k, k1, nb, rv;
189 carry = rv = 0;
190 b = d2b(dval(d), &e, &bdif);
191 bdif -= nb = fpi->nbits;
192 e += bdif;
193 if (bdif <= 0) {
194 if (exact)
195 goto trunc;
196 goto ret;
198 if (P == nb) {
199 if (
200 #ifndef IMPRECISE_INEXACT
201 exact &&
202 #endif
203 fpi->rounding ==
204 #ifdef RND_PRODQUOT
205 FPI_Round_near
206 #else
207 Flt_Rounds
208 #endif
209 ) goto trunc;
210 goto ret;
212 switch(rd) {
213 case 1: /* round down (toward -Infinity) */
214 goto trunc;
215 case 2: /* round up (toward +Infinity) */
216 break;
217 default: /* round near */
218 k = bdif - 1;
219 if (!k) {
220 if (!exact)
221 goto ret;
222 if (b->x[0] & 2)
223 break;
224 goto trunc;
226 if (b->x[(unsigned int)k>>kshift] & ((ULong)1 << (k & kmask)))
227 break;
228 goto trunc;
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 = ULbits - 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++;
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;
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[(unsigned int)k1>>kshift] &
268 (1 << (k1 & kmask));
269 rshift(b, k);
270 *irv = STRTOG_Denormal;
271 if (carry) {
272 b = increment(b);
273 inex = STRTOG_Inexhi | STRTOG_Underflow;
275 else if (lostbits)
276 inex = STRTOG_Inexlo | STRTOG_Underflow;
279 else if (e > fpi->emax) {
280 e = fpi->emax + 1;
281 *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
282 #ifndef NO_ERRNO
283 errno = ERANGE;
284 #endif
285 b->wds = inex = 0;
287 *expt = e;
288 copybits(bits, nb, b);
289 *irv |= inex;
290 rv = 1;
291 ret:
292 Bfree(b);
293 return rv;
296 #ifndef VAX
297 static int
298 #ifdef KR_headers
299 mantbits(d) U *d;
300 #else
301 mantbits(U *d)
302 #endif
304 ULong L;
305 #ifdef VAX
306 L = word1(d) << 16 | word1(d) >> 16;
307 if (L)
308 #else
309 if ( (L = word1(d)) !=0)
310 #endif
311 return P - lo0bits(&L);
312 #ifdef VAX
313 L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11;
314 #else
315 L = word0(d) | Exp_msk1;
316 #endif
317 return P - 32 - lo0bits(&L);
319 #endif /* !VAX */
322 strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *expt, ULong *bits,
323 locale_t loc)
325 int abe, abits, asub;
326 #ifdef INFNAN_CHECK
327 int decpt;
328 #endif
329 int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, denorm;
330 int dsign, e, e1, e2, emin, esign, finished, i, inex, irv;
331 int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign;
332 int sudden_underflow = 0; /* pacify gcc */
333 CONST char *s, *s0, *s1;
334 double adj0, tol;
335 Long L;
336 U adj, rv;
337 ULong *b, *be, y, z;
338 Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
339 #ifdef USE_LOCALE /*{{*/
340 char *decimalpoint = localeconv_l(loc)->decimal_point;
341 size_t dplen = strlen(decimalpoint);
342 #endif /*USE_LOCALE}}*/
344 e2 = 0; /* XXX gcc */
346 irv = STRTOG_Zero;
347 denorm = sign = nz0 = nz = 0;
348 dval(&rv) = 0.;
349 rvb = 0;
350 nbits = fpi->nbits;
351 for(s = s00;;s++) switch(*s) {
352 case '-':
353 sign = 1;
354 /* FALLTHROUGH */
355 case '+':
356 if (*++s)
357 goto break2;
358 /* FALLTHROUGH */
359 case 0:
360 sign = 0;
361 irv = STRTOG_NoNumber;
362 s = s00;
363 goto ret;
364 case '\t':
365 case '\n':
366 case '\v':
367 case '\f':
368 case '\r':
369 case ' ':
370 continue;
371 default:
372 goto break2;
374 break2:
375 if (*s == '0') {
376 #ifndef NO_HEX_FP
377 switch(s[1]) {
378 case 'x':
379 case 'X':
380 irv = gethex(&s, fpi, expt, &rvb, sign, loc);
381 if (irv == STRTOG_NoNumber) {
382 s = s00;
383 sign = 0;
385 goto ret;
387 #endif
388 nz0 = 1;
389 while(*++s == '0') ;
390 if (!*s)
391 goto ret;
393 sudden_underflow = fpi->sudden_underflow;
394 s0 = s;
395 y = z = 0;
396 #ifdef INFNAN_CHECK
397 decpt = 0;
398 #endif
399 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
400 if (nd < 9)
401 y = 10*y + c - '0';
402 else if (nd < 16)
403 z = 10*z + c - '0';
404 nd0 = nd;
405 #ifdef USE_LOCALE
406 if (c == *decimalpoint) {
407 for(i = 1; decimalpoint[i]; ++i)
408 if (s[i] != decimalpoint[i])
409 goto dig_done;
410 s += i;
411 c = *s;
412 #else
413 if (c == '.') {
414 c = *++s;
415 #endif
416 #ifdef INFNAN_CHECK
417 decpt = 1;
418 #endif
419 if (!nd) {
420 for(; c == '0'; c = *++s)
421 nz++;
422 if (c > '0' && c <= '9') {
423 s0 = s;
424 nf += nz;
425 nz = 0;
426 goto have_dig;
428 goto dig_done;
430 for(; c >= '0' && c <= '9'; c = *++s) {
431 have_dig:
432 nz++;
433 if (c -= '0') {
434 nf += nz;
435 for(i = 1; i < nz; i++)
436 if (nd++ < 9)
437 y *= 10;
438 else if (nd <= DBL_DIG + 1)
439 z *= 10;
440 if (nd++ < 9)
441 y = 10*y + c;
442 else if (nd <= DBL_DIG + 1)
443 z = 10*z + c;
444 nz = 0;
447 }/*}*/
448 dig_done:
449 e = 0;
450 if (c == 'e' || c == 'E') {
451 if (!nd && !nz && !nz0) {
452 irv = STRTOG_NoNumber;
453 s = s00;
454 goto ret;
456 s00 = s;
457 esign = 0;
458 switch(c = *++s) {
459 case '-':
460 esign = 1;
461 /* FALLTHROUGH */
462 case '+':
463 c = *++s;
465 if (c >= '0' && c <= '9') {
466 while(c == '0')
467 c = *++s;
468 if (c > '0' && c <= '9') {
469 L = c - '0';
470 s1 = s;
471 while((c = *++s) >= '0' && c <= '9')
472 L = 10*L + c - '0';
473 if (s - s1 > 8 || L > 19999)
474 /* Avoid confusion from exponents
475 * so large that e might overflow.
477 e = 19999; /* safe for 16 bit ints */
478 else
479 e = (int)L;
480 if (esign)
481 e = -e;
483 else
484 e = 0;
486 else
487 s = s00;
489 if (!nd) {
490 if (!nz && !nz0) {
491 #ifdef INFNAN_CHECK
492 /* Check for Nan and Infinity */
493 if (!decpt)
494 switch(c) {
495 case 'i':
496 case 'I':
497 if (match(&s,"nf")) {
498 --s;
499 if (!match(&s,"inity"))
500 ++s;
501 irv = STRTOG_Infinite;
502 goto infnanexp;
504 break;
505 case 'n':
506 case 'N':
507 if (match(&s, "an")) {
508 irv = STRTOG_NaN;
509 *expt = fpi->emax + 1;
510 #ifndef No_Hex_NaN
511 if (*s == '(') /*)*/
512 irv = hexnan(&s, fpi, bits);
513 #endif
514 goto infnanexp;
517 #endif /* INFNAN_CHECK */
518 irv = STRTOG_NoNumber;
519 s = s00;
521 goto ret;
524 irv = STRTOG_Normal;
525 e1 = e -= nf;
526 rd = 0;
527 switch(fpi->rounding & 3) {
528 case FPI_Round_up:
529 rd = 2 - sign;
530 break;
531 case FPI_Round_zero:
532 rd = 1;
533 break;
534 case FPI_Round_down:
535 rd = 1 + sign;
538 /* Now we have nd0 digits, starting at s0, followed by a
539 * decimal point, followed by nd-nd0 digits. The number we're
540 * after is the integer represented by those digits times
541 * 10**e */
543 if (!nd0)
544 nd0 = nd;
545 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
546 dval(&rv) = y;
547 if (k > 9)
548 dval(&rv) = tens[k - 9] * dval(&rv) + z;
549 bd0 = 0;
550 if (nbits <= P && nd <= DBL_DIG) {
551 if (!e) {
552 if (rvOK(&rv, fpi, expt, bits, 1, rd, &irv))
553 goto ret;
555 else if (e > 0) {
556 if (e <= Ten_pmax) {
557 #ifdef VAX
558 goto vax_ovfl_check;
559 #else
560 i = fivesbits[e] + mantbits(&rv) <= P;
561 /* rv = */ rounded_product(dval(&rv), tens[e]);
562 if (rvOK(&rv, fpi, expt, bits, i, rd, &irv))
563 goto ret;
564 e1 -= e;
565 goto rv_notOK;
566 #endif
568 i = DBL_DIG - nd;
569 if (e <= Ten_pmax + i) {
570 /* A fancier test would sometimes let us do
571 * this for larger i values.
573 e2 = e - i;
574 e1 -= i;
575 dval(&rv) *= tens[i];
576 #ifdef VAX
577 /* VAX exponent range is so narrow we must
578 * worry about overflow here...
580 vax_ovfl_check:
581 dval(&adj) = dval(&rv);
582 word0(&adj) -= P*Exp_msk1;
583 /* adj = */ rounded_product(dval(&adj), tens[e2]);
584 if ((word0(&adj) & Exp_mask)
585 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
586 goto rv_notOK;
587 word0(&adj) += P*Exp_msk1;
588 dval(&rv) = dval(&adj);
589 #else
590 /* rv = */ rounded_product(dval(&rv), tens[e2]);
591 #endif
592 if (rvOK(&rv, fpi, expt, bits, 0, rd, &irv))
593 goto ret;
594 e1 -= e2;
597 #ifndef Inaccurate_Divide
598 else if (e >= -Ten_pmax) {
599 /* rv = */ rounded_quotient(dval(&rv), tens[-e]);
600 if (rvOK(&rv, fpi, expt, bits, 0, rd, &irv))
601 goto ret;
602 e1 -= e;
604 #endif
606 rv_notOK:
607 e1 += nd - k;
609 /* Get starting approximation = rv * 10**e1 */
611 e2 = 0;
612 if (e1 > 0) {
613 if ( (i = e1 & 15) !=0)
614 dval(&rv) *= tens[i];
615 if (e1 &= ~15) {
616 e1 = (unsigned int)e1 >> 4;
617 while(e1 >= (1 << (n_bigtens-1))) {
618 e2 += ((word0(&rv) & Exp_mask)
619 >> Exp_shift1) - Bias;
620 word0(&rv) &= ~Exp_mask;
621 word0(&rv) |= Bias << Exp_shift1;
622 dval(&rv) *= bigtens[n_bigtens-1];
623 e1 -= 1 << (n_bigtens-1);
625 e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias;
626 word0(&rv) &= ~Exp_mask;
627 word0(&rv) |= Bias << Exp_shift1;
628 for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
629 if (e1 & 1)
630 dval(&rv) *= bigtens[j];
633 else if (e1 < 0) {
634 e1 = -e1;
635 if ( (i = e1 & 15) !=0)
636 dval(&rv) /= tens[i];
637 if (e1 &= ~15) {
638 e1 = (unsigned int)e1 >> 4;
639 while(e1 >= (1 << (n_bigtens-1))) {
640 e2 += ((word0(&rv) & Exp_mask)
641 >> Exp_shift1) - Bias;
642 word0(&rv) &= ~Exp_mask;
643 word0(&rv) |= Bias << Exp_shift1;
644 dval(&rv) *= tinytens[n_bigtens-1];
645 e1 -= 1 << (n_bigtens-1);
647 e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias;
648 word0(&rv) &= ~Exp_mask;
649 word0(&rv) |= Bias << Exp_shift1;
650 for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
651 if (e1 & 1)
652 dval(&rv) *= tinytens[j];
655 #ifdef IBM
656 /* e2 is a correction to the (base 2) exponent of the return
657 * value, reflecting adjustments above to avoid overflow in the
658 * native arithmetic. For native IBM (base 16) arithmetic, we
659 * must multiply e2 by 4 to change from base 16 to 2.
661 e2 <<= 2;
662 #endif
663 rvb = d2b(dval(&rv), &rve, &rvbits); /* rv = rvb * 2^rve */
664 if (rvb == NULL)
665 return STRTOG_NoMemory;
666 rve += e2;
667 if ((j = rvbits - nbits) > 0) {
668 rshift(rvb, j);
669 rvbits = nbits;
670 rve += j;
672 bb0 = 0; /* trailing zero bits in rvb */
673 e2 = rve + rvbits - nbits;
674 if (e2 > fpi->emax + 1)
675 goto huge;
676 rve1 = rve + rvbits - nbits;
677 if (e2 < (emin = fpi->emin)) {
678 denorm = 1;
679 j = rve - emin;
680 if (j > 0) {
681 rvb = lshift(rvb, j);
682 rvbits += j;
684 else if (j < 0) {
685 rvbits += j;
686 if (rvbits <= 0) {
687 if (rvbits < -1) {
688 ufl:
689 rvb->wds = 0;
690 rvb->x[0] = 0;
691 *expt = emin;
692 irv = STRTOG_Underflow | STRTOG_Inexlo;
693 goto ret;
695 rvb->x[0] = rvb->wds = rvbits = 1;
697 else
698 rshift(rvb, -j);
700 rve = rve1 = emin;
701 if (sudden_underflow && e2 + 1 < emin)
702 goto ufl;
705 /* Now the hard part -- adjusting rv to the correct value.*/
707 /* Put digits into bd: true value = bd * 10^e */
709 bd0 = s2b(s0, nd0, nd, y, dplen);
711 for(;;) {
712 bd = Balloc(bd0->k);
713 if (bd == NULL)
714 return STRTOG_NoMemory;
715 Bcopy(bd, bd0);
716 bb = Balloc(rvb->k);
717 if (bb == NULL)
718 return STRTOG_NoMemory;
719 Bcopy(bb, rvb);
720 bbbits = rvbits - bb0;
721 bbe = rve + bb0;
722 bs = i2b(1);
723 if (bs == NULL)
724 return STRTOG_NoMemory;
726 if (e >= 0) {
727 bb2 = bb5 = 0;
728 bd2 = bd5 = e;
730 else {
731 bb2 = bb5 = -e;
732 bd2 = bd5 = 0;
734 if (bbe >= 0)
735 bb2 += bbe;
736 else
737 bd2 -= bbe;
738 bs2 = bb2;
739 j = nbits + 1 - bbbits;
740 i = bbe + bbbits - nbits;
741 if (i < emin) /* denormal */
742 j += i - emin;
743 bb2 += j;
744 bd2 += j;
745 i = bb2 < bd2 ? bb2 : bd2;
746 if (i > bs2)
747 i = bs2;
748 if (i > 0) {
749 bb2 -= i;
750 bd2 -= i;
751 bs2 -= i;
753 if (bb5 > 0) {
754 bs = pow5mult(bs, bb5);
755 if (bs == NULL)
756 return STRTOG_NoMemory;
757 bb1 = mult(bs, bb);
758 if (bb1 == NULL)
759 return STRTOG_NoMemory;
760 Bfree(bb);
761 bb = bb1;
763 bb2 -= bb0;
764 if (bb2 > 0) {
765 bb = lshift(bb, bb2);
766 if (bb == NULL)
767 return STRTOG_NoMemory;
769 else if (bb2 < 0)
770 rshift(bb, -bb2);
771 if (bd5 > 0) {
772 bd = pow5mult(bd, bd5);
773 if (bd == NULL)
774 return STRTOG_NoMemory;
776 if (bd2 > 0) {
777 bd = lshift(bd, bd2);
778 if (bd == NULL)
779 return STRTOG_NoMemory;
781 if (bs2 > 0) {
782 bs = lshift(bs, bs2);
783 if (bs == NULL)
784 return STRTOG_NoMemory;
786 asub = 1;
787 inex = STRTOG_Inexhi;
788 delta = diff(bb, bd);
789 if (delta == NULL)
790 return STRTOG_NoMemory;
791 if (delta->wds <= 1 && !delta->x[0])
792 break;
793 dsign = delta->sign;
794 delta->sign = finished = 0;
795 L = 0;
796 i = cmp(delta, bs);
797 if (rd && i <= 0) {
798 irv = STRTOG_Normal;
799 if ( (finished = dsign ^ (rd&1)) !=0) {
800 if (dsign != 0) {
801 irv |= STRTOG_Inexhi;
802 goto adj1;
804 irv |= STRTOG_Inexlo;
805 if (rve1 == emin)
806 goto adj1;
807 for(i = 0, j = nbits; j >= ULbits;
808 i++, j -= ULbits) {
809 if (rvb->x[i] & ALL_ON)
810 goto adj1;
812 if (j > 1 && lo0bits(rvb->x + i) < j - 1)
813 goto adj1;
814 rve = rve1 - 1;
815 rvb = set_ones(rvb, rvbits = nbits);
816 if (rvb == NULL)
817 return STRTOG_NoMemory;
818 break;
820 irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi;
821 break;
823 if (i < 0) {
824 /* Error is less than half an ulp -- check for
825 * special case of mantissa a power of two.
827 irv = dsign
828 ? STRTOG_Normal | STRTOG_Inexlo
829 : STRTOG_Normal | STRTOG_Inexhi;
830 if (dsign || bbbits > 1 || denorm || rve1 == emin)
831 break;
832 delta = lshift(delta,1);
833 if (delta == NULL)
834 return STRTOG_NoMemory;
835 if (cmp(delta, bs) > 0) {
836 irv = STRTOG_Normal | STRTOG_Inexlo;
837 goto drop_down;
839 break;
841 if (i == 0) {
842 /* exactly half-way between */
843 if (dsign) {
844 if (denorm && all_on(rvb, rvbits)) {
845 /*boundary case -- increment exponent*/
846 rvb->wds = 1;
847 rvb->x[0] = 1;
848 rve = emin + nbits - (rvbits = 1);
849 irv = STRTOG_Normal | STRTOG_Inexhi;
850 denorm = 0;
851 break;
853 irv = STRTOG_Normal | STRTOG_Inexlo;
855 else if (bbbits == 1) {
856 irv = STRTOG_Normal;
857 drop_down:
858 /* boundary case -- decrement exponent */
859 if (rve1 == emin) {
860 irv = STRTOG_Normal | STRTOG_Inexhi;
861 if (rvb->wds == 1 && rvb->x[0] == 1)
862 sudden_underflow = 1;
863 break;
865 rve -= nbits;
866 rvb = set_ones(rvb, rvbits = nbits);
867 if (rvb == NULL)
868 return STRTOG_NoMemory;
869 break;
871 else
872 irv = STRTOG_Normal | STRTOG_Inexhi;
873 if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1))
874 break;
875 if (dsign) {
876 rvb = increment(rvb);
877 if (rvb == NULL)
878 return STRTOG_NoMemory;
879 j = kmask & (ULbits - (rvbits & kmask));
880 if (hi0bits(rvb->x[rvb->wds - 1]) != j)
881 rvbits++;
882 irv = STRTOG_Normal | STRTOG_Inexhi;
884 else {
885 if (bbbits == 1)
886 goto undfl;
887 decrement(rvb);
888 irv = STRTOG_Normal | STRTOG_Inexlo;
890 break;
892 if ((dval(&adj) = ratio(delta, bs)) <= 2.) {
893 adj1:
894 inex = STRTOG_Inexlo;
895 if (dsign) {
896 asub = 0;
897 inex = STRTOG_Inexhi;
899 else if (denorm && bbbits <= 1) {
900 undfl:
901 rvb->wds = 0;
902 rve = emin;
903 irv = STRTOG_Underflow | STRTOG_Inexlo;
904 break;
906 adj0 = dval(&adj) = 1.;
908 else {
909 adj0 = dval(&adj) *= 0.5;
910 if (dsign) {
911 asub = 0;
912 inex = STRTOG_Inexlo;
914 if (dval(&adj) < 2147483647.) {
915 L = adj0;
916 adj0 -= L;
917 switch(rd) {
918 case 0:
919 if (adj0 >= .5)
920 goto inc_L;
921 break;
922 case 1:
923 if (asub && adj0 > 0.)
924 goto inc_L;
925 break;
926 case 2:
927 if (!asub && adj0 > 0.) {
928 inc_L:
929 L++;
930 inex = STRTOG_Inexact - inex;
933 dval(&adj) = L;
936 y = rve + rvbits;
938 /* adj *= ulp(dval(&rv)); */
939 /* if (asub) rv -= adj; else rv += adj; */
941 if (!denorm && rvbits < nbits) {
942 rvb = lshift(rvb, j = nbits - rvbits);
943 if (rvb == NULL)
944 return STRTOG_NoMemory;
945 rve -= j;
946 rvbits = nbits;
948 ab = d2b(dval(&adj), &abe, &abits);
949 if (ab == NULL)
950 return STRTOG_NoMemory;
951 if (abe < 0)
952 rshift(ab, -abe);
953 else if (abe > 0)
954 ab = lshift(ab, abe);
955 rvb0 = rvb;
956 if (asub) {
957 /* rv -= adj; */
958 j = hi0bits(rvb->x[rvb->wds-1]);
959 rvb = diff(rvb, ab);
960 if (rvb == NULL)
961 return STRTOG_NoMemory;
962 k = rvb0->wds - 1;
963 if (denorm)
964 /* do nothing */;
965 else if (rvb->wds <= k
966 || hi0bits( rvb->x[k]) >
967 hi0bits(rvb0->x[k])) {
968 /* unlikely; can only have lost 1 high bit */
969 if (rve1 == emin) {
970 --rvbits;
971 denorm = 1;
973 else {
974 rvb = lshift(rvb, 1);
975 if (rvb == NULL)
976 return STRTOG_NoMemory;
977 --rve;
978 --rve1;
979 L = finished = 0;
983 else {
984 rvb = sum(rvb, ab);
985 if (rvb == NULL)
986 return STRTOG_NoMemory;
987 k = rvb->wds - 1;
988 if (k >= rvb0->wds
989 || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) {
990 if (denorm) {
991 if (++rvbits == nbits)
992 denorm = 0;
994 else {
995 rshift(rvb, 1);
996 rve++;
997 rve1++;
998 L = 0;
1002 Bfree(ab);
1003 Bfree(rvb0);
1004 if (finished)
1005 break;
1007 z = rve + rvbits;
1008 if (y == z && L) {
1009 /* Can we stop now? */
1010 tol = dval(&adj) * 5e-16; /* > max rel error */
1011 dval(&adj) = adj0 - .5;
1012 if (dval(&adj) < -tol) {
1013 if (adj0 > tol) {
1014 irv |= inex;
1015 break;
1018 else if (dval(&adj) > tol && adj0 < 1. - tol) {
1019 irv |= inex;
1020 break;
1023 bb0 = denorm ? 0 : trailz(rvb);
1024 Bfree(bb);
1025 Bfree(bd);
1026 Bfree(bs);
1027 Bfree(delta);
1029 if (!denorm && (j = nbits - rvbits)) {
1030 if (j > 0)
1031 rvb = lshift(rvb, j);
1032 else
1033 rshift(rvb, -j);
1034 rve -= j;
1036 *expt = rve;
1037 Bfree(bb);
1038 Bfree(bd);
1039 Bfree(bs);
1040 Bfree(bd0);
1041 Bfree(delta);
1042 if (rve > fpi->emax) {
1043 switch(fpi->rounding & 3) {
1044 case FPI_Round_near:
1045 goto huge;
1046 case FPI_Round_up:
1047 if (!sign)
1048 goto huge;
1049 break;
1050 case FPI_Round_down:
1051 if (sign)
1052 goto huge;
1054 /* Round to largest representable magnitude */
1055 Bfree(rvb);
1056 rvb = 0;
1057 irv = STRTOG_Normal | STRTOG_Inexlo;
1058 *expt = fpi->emax;
1059 b = bits;
1060 be = b + ((unsigned int)(fpi->nbits + 31) >> 5);
1061 while(b < be)
1062 *b++ = (unsigned int)-1;
1063 if ((j = fpi->nbits & 0x1f) != 0)
1064 *--be >>= (32 - j);
1065 goto ret;
1066 huge:
1067 rvb->wds = 0;
1068 irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
1069 #ifndef NO_ERRNO
1070 errno = ERANGE;
1071 #endif
1072 #ifdef INFNAN_CHECK
1073 infnanexp:
1074 #endif
1075 *expt = fpi->emax + 1;
1077 ret:
1078 if (denorm) {
1079 if (sudden_underflow) {
1080 rvb->wds = 0;
1081 irv = STRTOG_Underflow | STRTOG_Inexlo;
1082 #ifndef NO_ERRNO
1083 errno = ERANGE;
1084 #endif
1086 else {
1087 irv = (irv & ~STRTOG_Retmask) |
1088 (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero);
1089 if (irv & STRTOG_Inexact) {
1090 irv |= STRTOG_Underflow;
1091 #ifndef NO_ERRNO
1092 errno = ERANGE;
1093 #endif
1097 if (se)
1098 *se = __UNCONST(s);
1099 if (sign)
1100 irv |= STRTOG_Neg;
1101 if (rvb) {
1102 copybits(bits, nbits, rvb);
1103 Bfree(rvb);
1105 return irv;