14bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes/**************************************************************** 24bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 34bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesThe author of this software is David M. Gay. 44bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 54bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesCopyright (C) 1998, 1999 by Lucent Technologies 64bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesAll Rights Reserved 74bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 84bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesPermission to use, copy, modify, and distribute this software and 94bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesits documentation for any purpose and without fee is hereby 104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesgranted, provided that the above copyright notice appear in all 114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughescopies and that both that the copyright notice and this 124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughespermission notice and warranty disclaimer appear in supporting 134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesdocumentation, and that the name of Lucent or any of its entities 144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesnot be used in advertising or publicity pertaining to 154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesdistribution of the software without specific, written prior 164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughespermission. 174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesTHIS SOFTWARE. 264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes****************************************************************/ 284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes/* Please send bug reports to David M. Gay (dmg at acm dot org, 304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * with " at " changed at "@" and " dot " changed to "."). */ 314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#include "gdtoaimp.h" 334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. 354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * Inspired by "How to Print Floating-Point Numbers Accurately" by 374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. 384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * Modifications: 404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 1. Rather than iterating, we use a simple numeric overestimate 414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * to determine k = floor(log10(d)). We scale relevant 424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * quantities using O(log2(k)) rather than O(k) multiplications. 434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't 444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * try to generate digits strictly left to right. Instead, we 454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * compute with fewer bits and propagate the carry if necessary 464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * when rounding the final digit up. This is often faster. 474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 3. Under the assumption that input will be rounded nearest, 484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. 494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * That is, we allow equality in stopping tests when the 504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * round-nearest rule will give the same floating-point value 514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * as would satisfaction of the stopping test with strict 524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * inequality. 534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 4. We remove common factors of powers of 2 from relevant 544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * quantities. 554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 5. When converting floating-point integers less than 1e16, 564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * we use floating-point arithmetic rather than resorting 574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * to multiple-precision integers. 584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 6. When asked to produce fewer than 15 digits, we first try 594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * to get by with floating-point arithmetic; we resort to 604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * multiple-precision integer arithmetic only if we cannot 614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * guarantee that the floating-point calculation has given 624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * the correctly rounded result. For k requested digits and 634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * "uniformly" distributed input, the probability is 644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * something like 10^(k-15) that we must resort to the Long 654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * calculation. 664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes */ 674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#undef Check_FLT_ROUNDS 704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#define Check_FLT_ROUNDS 714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#define Rounding Flt_Rounds 734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes char * 764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesdtoa 774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef KR_headers 784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes (d0, mode, ndigits, decpt, sign, rve) 794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes double d0; int mode, ndigits, *decpt, *sign; char **rve; 804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes (double d0, int mode, int ndigits, int *decpt, int *sign, char **rve) 824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes{ 844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Arguments ndigits, decpt, sign are similar to those 854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes of ecvt and fcvt; trailing zeros are suppressed from 864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes the returned string. If not null, *rve is set to point 874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes to the end of the return value. If d is +-Infinity or NaN, 884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes then *decpt is set to 9999. 894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mode: 914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 0 ==> shortest string that yields d when read in 924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes and rounded to nearest. 934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1 ==> like 0, but with Steele & White stopping rule; 944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes e.g. with IEEE P754 arithmetic , mode 0 gives 954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1e23 whereas mode 1 gives 9.999999999999999e22. 964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 2 ==> max(1,ndigits) significant digits. This gives a 974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return value similar to that of ecvt, except 984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes that trailing zeros are suppressed. 994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 3 ==> through ndigits past the decimal point. This 1004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes gives a return value similar to that from fcvt, 1014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes except that trailing zeros are suppressed, and 1024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ndigits can be negative. 1034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 4,5 ==> similar to 2 and 3, respectively, but (in 1044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes round-nearest mode) with the tests of mode 0 to 1054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes possibly return a shorter string that rounds to d. 1064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes With IEEE arithmetic and compilation with 1074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same 1084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes as modes 2 and 3 when FLT_ROUNDS != 1. 1094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 6-9 ==> Debugging modes similar to mode - 4: don't try 1104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes fast floating-point estimate (if applicable). 1114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Values of mode other than 0-9 are treated as mode 0. 1134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Sufficient space is allocated to the return value 1154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes to hold the suppressed trailing zeros. 1164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes */ 1174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, 1194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, 1204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes spec_case, try_quick; 1214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Long L; 1224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef Sudden_Underflow 1234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes int denorm; 1244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ULong x; 1254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 1264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Bigint *b, *b1, *delta, *mlo, *mhi, *S; 1274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes U d, d2, eps; 1284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes double ds; 1294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes char *s, *s0; 1304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT 1314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes int inexact, oldinexact; 1324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 1334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS /*{*/ 1344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes int Rounding; 1354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ 1364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Rounding = Flt_Rounds; 1374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else /*}{*/ 1384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Rounding = 1; 1394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes switch(fegetround()) { 1404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case FE_TOWARDZERO: Rounding = 0; break; 1414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case FE_UPWARD: Rounding = 2; break; 1424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case FE_DOWNWARD: Rounding = 3; 1434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 1444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif /*}}*/ 1454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif /*}*/ 1464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef MULTIPLE_THREADS 1484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dtoa_result) { 1494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes freedtoa(dtoa_result); 1504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dtoa_result = 0; 1514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 1524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 1534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes d.d = d0; 1544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (word0(&d) & Sign_bit) { 1554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* set sign for everything, including 0's and NaNs */ 1564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *sign = 1; 1574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes word0(&d) &= ~Sign_bit; /* clear sign bit */ 1584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 1594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else 1604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *sign = 0; 1614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#if defined(IEEE_Arith) + defined(VAX) 1634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IEEE_Arith 1644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if ((word0(&d) & Exp_mask) == Exp_mask) 1654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 1664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (word0(&d) == 0x8000) 1674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 1684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes { 1694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Infinity or NaN */ 1704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *decpt = 9999; 1714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IEEE_Arith 1724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (!word1(&d) && !(word0(&d) & 0xfffff)) 1734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return nrv_alloc("Infinity", rve, 8); 1744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 1754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return nrv_alloc("NaN", rve, 3); 1764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 1774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 1784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IBM 1794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) += 0; /* normalize */ 1804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 1814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (!dval(&d)) { 1824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *decpt = 1; 1834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return nrv_alloc("0", rve, 1); 1844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 1854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT 1874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes try_quick = oldinexact = get_inexact(); 1884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes inexact = 1; 1894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 1904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 1914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (Rounding >= 2) { 1924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (*sign) 1934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Rounding = Rounding == 2 ? 0 : 2; 1944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else 1954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (Rounding != 2) 1964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Rounding = 0; 1974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 1984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 1994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 2004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = d2b(dval(&d), &be, &bbits); 2014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b == NULL) 2024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 2034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Sudden_Underflow 2044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); 2054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 2064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { 2074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 2084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d2) = dval(&d); 2094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes word0(&d2) &= Frac_mask1; 2104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes word0(&d2) |= Exp_11; 2114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IBM 2124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (( j = 11 - hi0bits(word0(&d2) & Frac_mask) )!=0) 2134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d2) /= 1 << j; 2144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 2154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 2164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 2174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * log10(x) = log(x) / log(10) 2184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) 2194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * log10(&d) = (i-Bias)*log(2)/log(10) + log10(&d2) 2204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 2214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * This suggests computing an approximation k to log10(&d) by 2224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 2234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * k = (i - Bias)*0.301029995663981 2244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); 2254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 2264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * We want k to be too large rather than too small. 2274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * The error in the first-order Taylor series approximation 2284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * is in our favor, so we just round up the constant enough 2294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * to compensate for any error in the multiplication of 2304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, 2314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, 2324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * adding 1e-13 to the constant term more than suffices. 2334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * Hence we adjust the constant term to 0.1760912590558. 2344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * (We could get a more accurate k by invoking log10, 2354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * but this is probably not worthwhile.) 2364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes */ 2374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 2384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i -= Bias; 2394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IBM 2404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i <<= 2; 2414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i += j; 2424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 2434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef Sudden_Underflow 2444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes denorm = 0; 2454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 2464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else { 2474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* d is denormalized */ 2484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 2494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = bbits + be + (Bias + (P-1) - 1); 2504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes x = i > 32 ? word0(&d) << (64 - i) | word1(&d) >> (i - 32) 2514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes : word1(&d) << (32 - i); 2524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d2) = x; 2534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ 2544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i -= (Bias + (P-1) - 1) + 1; 2554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes denorm = 1; 2564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 2574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 2584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; 2594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k = (int)ds; 2604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (ds < 0. && ds != k) 2614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k--; /* want k = floor(ds) */ 2624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k_check = 1; 2634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (k >= 0 && k <= Ten_pmax) { 2644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dval(&d) < tens[k]) 2654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k--; 2664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k_check = 0; 2674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 2684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes j = bbits - i - 1; 2694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j >= 0) { 2704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b2 = 0; 2714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s2 = j; 2724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 2734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else { 2744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b2 = -j; 2754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s2 = 0; 2764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 2774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (k >= 0) { 2784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b5 = 0; 2794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s5 = k; 2804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s2 += k; 2814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 2824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else { 2834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b2 -= k; 2844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b5 = -k; 2854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s5 = 0; 2864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 2874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mode < 0 || mode > 9) 2884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mode = 0; 2894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 2904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef SET_INEXACT 2914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Check_FLT_ROUNDS 2924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes try_quick = Rounding == 1; 2934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 2944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes try_quick = 1; 2954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 2964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif /*SET_INEXACT*/ 2974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 2984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mode > 5) { 2994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mode -= 4; 3004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes try_quick = 0; 3014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 3024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes leftright = 1; 3034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ 3044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* silence erroneous "gcc -Wall" warning. */ 3054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes switch(mode) { 3064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 0: 3074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 1: 3084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = 18; 3094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ndigits = 0; 3104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes break; 3114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 2: 3124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes leftright = 0; 3134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* no break */ 3144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 4: 3154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (ndigits <= 0) 3164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ndigits = 1; 3174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ilim = ilim1 = i = ndigits; 3184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes break; 3194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 3: 3204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes leftright = 0; 3214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* no break */ 3224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 5: 3234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = ndigits + k + 1; 3244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ilim = i; 3254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ilim1 = i - 1; 3264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (i <= 0) 3274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = 1; 3284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 3294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s = s0 = rv_alloc(i); 3304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (s == NULL) 3314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 3324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 3334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 3344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mode > 1 && Rounding != 1) 3354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes leftright = 0; 3364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 3374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 3384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (ilim >= 0 && ilim <= Quick_max && try_quick) { 3394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 3404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Try to get by with floating-point arithmetic. */ 3414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 3424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = 0; 3434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d2) = dval(&d); 3444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k0 = k; 3454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ilim0 = ilim; 3464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ieps = 2; /* conservative */ 3474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (k > 0) { 3484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ds = tens[k&0xf]; 3494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes j = k >> 4; 3504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j & Bletch) { 3514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* prevent overflows */ 3524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes j &= Bletch - 1; 3534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) /= bigtens[n_bigtens-1]; 3544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ieps++; 3554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 3564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes for(; j; j >>= 1, i++) 3574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j & 1) { 3584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ieps++; 3594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ds *= bigtens[i]; 3604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 3614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) /= ds; 3624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 3634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else if (( j1 = -k )!=0) { 3644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) *= tens[j1 & 0xf]; 3654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes for(j = j1 >> 4; j; j >>= 1, i++) 3664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j & 1) { 3674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ieps++; 3684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) *= bigtens[i]; 3694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 3704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 3714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (k_check && dval(&d) < 1. && ilim > 0) { 3724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (ilim1 <= 0) 3734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto fast_failed; 3744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ilim = ilim1; 3754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k--; 3764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) *= 10.; 3774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ieps++; 3784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 3794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&eps) = ieps*dval(&d) + 7.; 3804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes word0(&eps) -= (P-1)*Exp_msk1; 3814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (ilim == 0) { 3824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes S = mhi = 0; 3834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) -= 5.; 3844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dval(&d) > dval(&eps)) 3854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto one_digit; 3864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dval(&d) < -dval(&eps)) 3874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto no_digits; 3884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto fast_failed; 3894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 3904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef No_leftright 3914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (leftright) { 3924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Use Steele & White method of only 3934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * generating digits needed. 3944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes */ 3954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); 3964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes for(i = 0;;) { 3974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes L = dval(&d); 3984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) -= L; 3994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = '0' + (int)L; 4004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dval(&d) < dval(&eps)) 4014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret1; 4024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (1. - dval(&d) < dval(&eps)) 4034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto bump_up; 4044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (++i >= ilim) 4054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes break; 4064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&eps) *= 10.; 4074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) *= 10.; 4084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else { 4114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 4124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Generate ilim digits, then fix them up. */ 4134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&eps) *= tens[ilim-1]; 4144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes for(i = 1;; i++, dval(&d) *= 10.) { 4154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes L = (Long)(dval(&d)); 4164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (!(dval(&d) -= L)) 4174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ilim = i; 4184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = '0' + (int)L; 4194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (i == ilim) { 4204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dval(&d) > 0.5 + dval(&eps)) 4214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto bump_up; 4224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else if (dval(&d) < 0.5 - dval(&eps)) { 4234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes while(*--s == '0'); 4244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s++; 4254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret1; 4264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes break; 4284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef No_leftright 4314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 4334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes fast_failed: 4344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s = s0; 4354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) = dval(&d2); 4364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k = k0; 4374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ilim = ilim0; 4384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 4404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Do we have a "small" integer? */ 4414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 4424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (be >= 0 && k <= Int_max) { 4434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Yes. */ 4444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ds = tens[k]; 4454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (ndigits < 0 && ilim <= 0) { 4464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes S = mhi = 0; 4474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (ilim < 0 || dval(&d) <= 5*ds) 4484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto no_digits; 4494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto one_digit; 4504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes for(i = 1;; i++, dval(&d) *= 10.) { 4524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes L = (Long)(dval(&d) / ds); 4534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) -= L*ds; 4544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Check_FLT_ROUNDS 4554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* If FLT_ROUNDS == 2, L will usually be high by 1 */ 4564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dval(&d) < 0) { 4574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes L--; 4584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) += ds; 4594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 4614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = '0' + (int)L; 4624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (!dval(&d)) { 4634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT 4644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes inexact = 0; 4654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 4664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes break; 4674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (i == ilim) { 4694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 4704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mode > 1) 4714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes switch(Rounding) { 4724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 0: goto ret1; 4734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 2: goto bump_up; 4744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 4764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) += dval(&d); 4774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef ROUND_BIASED 4784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dval(&d) >= ds) 4794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 4804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dval(&d) > ds || (dval(&d) == ds && L & 1)) 4814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 4824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes { 4834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes bump_up: 4844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes while(*--s == '9') 4854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (s == s0) { 4864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k++; 4874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s = '0'; 4884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes break; 4894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ++*s++; 4914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes break; 4934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret1; 4964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 4974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 4984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes m2 = b2; 4994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes m5 = b5; 5004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mhi = mlo = 0; 5014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (leftright) { 5024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = 5034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef Sudden_Underflow 5044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes denorm ? be + (Bias + (P-1) - 1 + 1) : 5054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 5064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IBM 5074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); 5084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 5094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 1 + P - bbits; 5104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 5114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b2 += i; 5124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s2 += i; 5134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mhi = i2b(1); 5144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mhi == NULL) 5154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 5164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (m2 > 0 && s2 > 0) { 5184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = m2 < s2 ? m2 : s2; 5194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b2 -= i; 5204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes m2 -= i; 5214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s2 -= i; 5224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b5 > 0) { 5244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (leftright) { 5254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (m5 > 0) { 5264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mhi = pow5mult(mhi, m5); 5274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mhi == NULL) 5284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 5294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b1 = mult(mhi, b); 5304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b1 == NULL) 5314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 5324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Bfree(b); 5334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = b1; 5344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (( j = b5 - m5 )!=0) { 5364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = pow5mult(b, j); 5374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b == NULL) 5384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 5394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else { 5424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = pow5mult(b, b5); 5434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b == NULL) 5444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 5454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes S = i2b(1); 5484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (S == NULL) 5494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 5504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (s5 > 0) { 5514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes S = pow5mult(S, s5); 5524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (S == NULL) 5534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 5544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 5564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Check for special case that d is a normalized power of 2. */ 5574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 5584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes spec_case = 0; 5594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if ((mode < 2 || leftright) 5604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 5614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes && Rounding == 1 5624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 5634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ) { 5644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (!word1(&d) && !(word0(&d) & Bndry_mask) 5654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef Sudden_Underflow 5664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes && word0(&d) & (Exp_mask & ~Exp_msk1) 5674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 5684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ) { 5694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* The special case */ 5704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b2 += Log2P; 5714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s2 += Log2P; 5724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes spec_case = 1; 5734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 5764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Arrange for convenient computation of quotients: 5774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * shift left if necessary so divisor has 4 leading 0 bits. 5784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * 5794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * Perhaps we should just compute leading 28 bits of S once 5804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * and for all and pass them and a shift to quorem, so it 5814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * can do shifts and ors to compute the numerator for q. 5824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes */ 5834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Pack_32 5844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0) 5854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = 32 - i; 5864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 5874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0) 5884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i = 16 - i; 5894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 5904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (i > 4) { 5914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i -= 4; 5924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b2 += i; 5934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes m2 += i; 5944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s2 += i; 5954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 5964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else if (i < 4) { 5974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes i += 28; 5984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b2 += i; 5994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes m2 += i; 6004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s2 += i; 6014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b2 > 0) { 6034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = lshift(b, b2); 6044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b == NULL) 6054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 6064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (s2 > 0) { 6084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes S = lshift(S, s2); 6094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (S == NULL) 6104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 6114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (k_check) { 6134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (cmp(b,S) < 0) { 6144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k--; 6154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = multadd(b, 10, 0); /* we botched the k estimate */ 6164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b == NULL) 6174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 6184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (leftright) { 6194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mhi = multadd(mhi, 10, 0); 6204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mhi == NULL) 6214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 6224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ilim = ilim1; 6244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (ilim <= 0 && (mode == 3 || mode == 5)) { 6274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes S = multadd(S,5,0); 6284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (S == NULL) 6294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 6304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (ilim < 0 || cmp(b,S) <= 0) { 6314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* no digits, fcvt style */ 6324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes no_digits: 6334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k = -1 - ndigits; 6344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret; 6354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes one_digit: 6374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = '1'; 6384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k++; 6394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret; 6404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (leftright) { 6424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (m2 > 0) { 6434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mhi = lshift(mhi, m2); 6444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mhi == NULL) 6454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 6464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 6484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Compute mlo -- check for special case 6494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * that d is a normalized power of 2. 6504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes */ 6514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 6524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mlo = mhi; 6534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (spec_case) { 6544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mhi = Balloc(mhi->k); 6554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mhi == NULL) 6564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 6574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Bcopy(mhi, mlo); 6584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mhi = lshift(mhi, Log2P); 6594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mhi == NULL) 6604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 6614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 6634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes for(i = 1;;i++) { 6644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dig = quorem(b,S) + '0'; 6654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Do we yet have the shortest decimal string 6664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * that will round to d? 6674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes */ 6684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes j = cmp(b, mlo); 6694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes delta = diff(S, mhi); 6704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (delta == NULL) 6714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 6724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes j1 = delta->sign ? 1 : cmp(b, delta); 6734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Bfree(delta); 6744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef ROUND_BIASED 6754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j1 == 0 && mode != 1 && !(word1(&d) & 1) 6764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 6774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes && Rounding >= 1 6784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 6794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ) { 6804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dig == '9') 6814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto round_9_up; 6824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j > 0) 6834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dig++; 6844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT 6854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else if (!b->x[0] && b->wds <= 1) 6864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes inexact = 0; 6874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 6884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = dig; 6894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret; 6904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 6914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 6924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j < 0 || (j == 0 && mode != 1 6934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef ROUND_BIASED 6944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes && !(word1(&d) & 1) 6954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 6964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes )) { 6974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (!b->x[0] && b->wds <= 1) { 6984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT 6994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes inexact = 0; 7004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 7014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto accept_dig; 7024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 7044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mode > 1) 7054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes switch(Rounding) { 7064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 0: goto accept_dig; 7074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 2: goto keep_dig; 7084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif /*Honor_FLT_ROUNDS*/ 7104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j1 > 0) { 7114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = lshift(b, 1); 7124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b == NULL) 7134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 7144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes j1 = cmp(b, S); 7154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef ROUND_BIASED 7164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j1 >= 0 /*)*/ 7174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 7184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if ((j1 > 0 || (j1 == 0 && dig & 1)) 7194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 7204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes && dig++ == '9') 7214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto round_9_up; 7224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes accept_dig: 7244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = dig; 7254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret; 7264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j1 > 0) { 7284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 7294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (!Rounding) 7304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto accept_dig; 7314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 7324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (dig == '9') { /* possible if i == 1 */ 7334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes round_9_up: 7344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = '9'; 7354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto roundoff; 7364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = dig + 1; 7384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret; 7394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 7414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes keep_dig: 7424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 7434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = dig; 7444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (i == ilim) 7454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes break; 7464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = multadd(b, 10, 0); 7474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b == NULL) 7484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 7494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mlo == mhi) { 7504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mlo = mhi = multadd(mhi, 10, 0); 7514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mlo == NULL) 7524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 7534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else { 7554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mlo = multadd(mlo, 10, 0); 7564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mlo == NULL) 7574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 7584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes mhi = multadd(mhi, 10, 0); 7594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mhi == NULL) 7604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 7614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else 7654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes for(i = 1;; i++) { 7664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = dig = quorem(b,S) + '0'; 7674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (!b->x[0] && b->wds <= 1) { 7684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT 7694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes inexact = 0; 7704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 7714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret; 7724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (i >= ilim) 7744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes break; 7754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = multadd(b, 10, 0); 7764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b == NULL) 7774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 7784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 7804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /* Round off last digit */ 7814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes 7824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 7834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes switch(Rounding) { 7844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 0: goto trimzeros; 7854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes case 2: goto roundoff; 7864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 7874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 7884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes b = lshift(b, 1); 7894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (b == NULL) 7904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return (NULL); 7914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes j = cmp(b, S); 7924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef ROUND_BIASED 7934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j >= 0) 7944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else 7954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (j > 0 || (j == 0 && dig & 1)) 7964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 7974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes { 7984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes roundoff: 7994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes while(*--s == '9') 8004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (s == s0) { 8014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes k++; 8024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s++ = '1'; 8034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes goto ret; 8044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 8054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ++*s++; 8064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 8074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else { 8084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS 8094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes trimzeros: 8104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 8114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes while(*--s == '0'); 8124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes s++; 8134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 8144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ret: 8154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Bfree(S); 8164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mhi) { 8174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (mlo && mlo != mhi) 8184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Bfree(mlo); 8194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Bfree(mhi); 8204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 8214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ret1: 8224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT 8234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (inexact) { 8244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (!oldinexact) { 8254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes word0(&d) = Exp_1 + (70 << Exp_shift); 8264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes word1(&d) = 0; 8274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes dval(&d) += 1.; 8284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 8294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 8304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes else if (!oldinexact) 8314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes clear_inexact(); 8324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif 8334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes Bfree(b); 8344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *s = 0; 8354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *decpt = k + 1; 8364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes if (rve) 8374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *rve = s; 8384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes return s0; 8394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes } 840