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