strtod.c (174679) | strtod.c (182709) |
---|---|
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 --- 15 unchanged lines hidden (view full) --- 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 | 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 --- 15 unchanged lines hidden (view full) --- 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/* $FreeBSD: head/contrib/gdtoa/strtod.c 174679 2007-12-16 21:14:33Z das $ */ | 32/* $FreeBSD: head/contrib/gdtoa/strtod.c 182709 2008-09-03 07:23:57Z das $ */ |
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 | 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 */ | 47/* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */ |
48/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ 49static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, | 48/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ 49static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, |
50 9007199254740992.e-256 | 50 9007199254740992.*9007199254740992.e-256 |
51 }; 52#endif 53#endif 54 55#ifdef Honor_FLT_ROUNDS | 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 64strtod --- 11 unchanged lines hidden (view full) --- 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 | 56#undef Check_FLT_ROUNDS 57#define Check_FLT_ROUNDS 58#else 59#define Rounding Flt_Rounds 60#endif 61 62 double 63strtod --- 11 unchanged lines hidden (view full) --- 75 CONST char *s, *s0, *s1; 76 double aadj, aadj1, adj, rv, rv0; 77 Long L; 78 ULong y, z; 79 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; 80#ifdef SET_INEXACT 81 int inexact, oldinexact; 82#endif |
84#ifdef Honor_FLT_ROUNDS 85 int rounding; 86#endif | 83#ifdef Honor_FLT_ROUNDS /*{*/ 84 int Rounding; 85#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ 86 Rounding = Flt_Rounds; 87#else /*}{*/ 88 Rounding = 1; 89 switch(fegetround()) { 90 case FE_TOWARDZERO: Rounding = 0; break; 91 case FE_UPWARD: Rounding = 2; break; 92 case FE_DOWNWARD: Rounding = 3; 93 } 94#endif /*}}*/ 95#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 '+': --- 9 unchanged lines hidden (view full) --- 104 case '\r': 105 case ' ': 106 continue; 107 default: 108 goto break2; 109 } 110 break2: 111 if (*s == '0') { | 96 97 sign = nz0 = nz = decpt = 0; 98 dval(rv) = 0.; 99 for(s = s00;;s++) switch(*s) { 100 case '-': 101 sign = 1; 102 /* no break */ 103 case '+': --- 9 unchanged lines hidden (view full) --- 113 case '\r': 114 case ' ': 115 continue; 116 default: 117 goto break2; 118 } 119 break2: 120 if (*s == '0') { |
112#ifndef NO_HEX_FP | 121#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 { | 122 { 123 static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; 124 Long exp; 125 ULong bits[2]; 126 switch(s[1]) { 127 case 'x': 128 case 'X': 129 { |
121#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) | 130#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) /*{{*/ |
122 FPI fpi1 = fpi; | 131 FPI fpi1 = fpi; |
132#ifdef Honor_FLT_ROUNDS /*{{*/ 133 fpi1.rounding = Rounding; 134#else /*}{*/ |
|
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 } | 135 switch(fegetround()) { 136 case FE_TOWARDZERO: fpi1.rounding = 0; break; 137 case FE_UPWARD: fpi1.rounding = 2; break; 138 case FE_DOWNWARD: fpi1.rounding = 3; 139 } |
128#else | 140#endif /*}}*/ 141#else /*}{*/ |
129#define fpi1 fpi | 142#define fpi1 fpi |
130#endif | 143#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) { --- 237 unchanged lines hidden (view full) --- 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 | 144 switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { 145 case STRTOG_NoNumber: 146 s = s00; 147 sign = 0; 148 case STRTOG_Zero: 149 break; 150 default: 151 if (bb) { --- 237 unchanged lines hidden (view full) --- 389 inexact = 1; 390 if (k <= DBL_DIG) 391 oldinexact = get_inexact(); 392#endif 393#ifdef Avoid_Underflow 394 scale = 0; 395#endif 396#ifdef Honor_FLT_ROUNDS |
384 if ((rounding = Flt_Rounds) >= 2) { | 397 if (Rounding >= 2) { |
385 if (sign) | 398 if (sign) |
386 rounding = rounding == 2 ? 0 : 2; | 399 Rounding = Rounding == 2 ? 0 : 2; |
387 else | 400 else |
388 if (rounding != 2) 389 rounding = 0; | 401 if (Rounding != 2) 402 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 | 403 } 404#endif 405#endif /*IEEE_Arith*/ 406 407 /* Get starting approximation = rv * 10**e1 */ 408 409 if (e1 > 0) { 410 if ( (i = e1 & 15) !=0) 411 dval(rv) *= tens[i]; 412 if (e1 &= ~15) { 413 if (e1 > DBL_MAX_10_EXP) { 414 ovfl: 415#ifndef NO_ERRNO 416 errno = ERANGE; 417#endif 418 /* Can't trust HUGE_VAL */ 419#ifdef IEEE_Arith 420#ifdef Honor_FLT_ROUNDS |
408 switch(rounding) { | 421 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; --- 114 unchanged lines hidden (view full) --- 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 | 422 case 0: /* toward 0 */ 423 case 3: /* toward -infinity */ 424 word0(rv) = Big0; 425 word1(rv) = Big1; 426 break; 427 default: 428 word0(rv) = Exp_mask; 429 word1(rv) = 0; --- 114 unchanged lines hidden (view full) --- 544 bd2 = bd5 = 0; 545 } 546 if (bbe >= 0) 547 bb2 += bbe; 548 else 549 bd2 -= bbe; 550 bs2 = bb2; 551#ifdef Honor_FLT_ROUNDS |
539 if (rounding != 1) | 552 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 --- 41 unchanged lines hidden (view full) --- 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 | 553 bs2++; 554#endif 555#ifdef Avoid_Underflow 556 j = bbe - scale; 557 i = j + bbbits - 1; /* logb(rv) */ 558 if (i < Emin) /* denormal */ 559 j += P - Emin; 560 else --- 41 unchanged lines hidden (view full) --- 602 bd = lshift(bd, bd2); 603 if (bs2 > 0) 604 bs = lshift(bs, bs2); 605 delta = diff(bb, bd); 606 dsign = delta->sign; 607 delta->sign = 0; 608 i = cmp(delta, bs); 609#ifdef Honor_FLT_ROUNDS |
597 if (rounding != 1) { | 610 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 } | 611 if (i < 0) { 612 /* Error is less than an ulp */ 613 if (!delta->x[0] && delta->wds <= 1) { 614 /* exact */ 615#ifdef SET_INEXACT 616 inexact = 0; 617#endif 618 break; 619 } |
607 if (rounding) { | 620 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) --- 29 unchanged lines hidden (view full) --- 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) { | 621 if (dsign) { 622 adj = 1.; 623 goto apply_adj; 624 } 625 } 626 else if (!dsign) { 627 adj = -1.; 628 if (!word1(rv) --- 29 unchanged lines hidden (view full) --- 658 dval(rv) += adj*ulp(dval(rv)); 659 } 660 break; 661 } 662 adj = ratio(delta, bs); 663 if (adj < 1.) 664 adj = 1.; 665 if (adj <= 0x7ffffffe) { |
653 /* adj = rounding ? ceil(adj) : floor(adj); */ | 666 /* adj = Rounding ? ceil(adj) : floor(adj); */ |
654 y = adj; 655 if (y != adj) { | 667 y = adj; 668 if (y != adj) { |
656 if (!((rounding>>1) ^ dsign)) | 669 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 --- 6 unchanged lines hidden (view full) --- 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)); | 670 y++; 671 adj = y; 672 } 673 } 674#ifdef Avoid_Underflow 675 if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) 676 word0(adj) += (2*P+1)*Exp_msk1 - y; 677#else --- 6 unchanged lines hidden (view full) --- 684 else 685 dval(rv) -= adj; 686 word0(rv) -= P*Exp_msk1; 687 goto cont; 688 } 689#endif /*Sudden_Underflow*/ 690#endif /*Avoid_Underflow*/ 691 adj *= ulp(dval(rv)); |
679 if (dsign) | 692 if (dsign) { 693 if (word0(rv) == Big0 && word1(rv) == Big1) 694 goto ovfl; |
680 dval(rv) += adj; | 695 dval(rv) += adj; |
696 } |
|
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 --- 76 unchanged lines hidden (view full) --- 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; | 697 else 698 dval(rv) -= adj; 699 goto cont; 700 } 701#endif /*Honor_FLT_ROUNDS*/ 702 703 if (i < 0) { 704 /* Error is less than half an ulp -- check for --- 76 unchanged lines hidden (view full) --- 781 /* accept rv */ 782 break; 783 /* rv = smallest denormal */ 784 goto undfl; 785 } 786 } 787#endif /*Avoid_Underflow*/ 788 L = (word0(rv) & Exp_mask) - Exp_msk1; |
773#endif /*Sudden_Underflow}*/ | 789#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 } --- 203 unchanged lines hidden --- | 790 word0(rv) = L | Bndry_mask1; 791 word1(rv) = 0xffffffff; 792#ifdef IBM 793 goto cont; 794#else 795 break; 796#endif 797 } --- 203 unchanged lines hidden --- |