+++ /dev/null
-/* $NetBSD: dtoa.c,v 1.3.4.1.4.1 2008/04/08 21:10:55 jdc Exp $ */\r
-\r
-/****************************************************************\r
-\r
-The author of this software is David M. Gay.\r
-\r
-Copyright (C) 1998, 1999 by Lucent Technologies\r
-All Rights Reserved\r
-\r
-Permission to use, copy, modify, and distribute this software and\r
-its documentation for any purpose and without fee is hereby\r
-granted, provided that the above copyright notice appear in all\r
-copies and that both that the copyright notice and this\r
-permission notice and warranty disclaimer appear in supporting\r
-documentation, and that the name of Lucent or any of its entities\r
-not be used in advertising or publicity pertaining to\r
-distribution of the software without specific, written prior\r
-permission.\r
-\r
-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,\r
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.\r
-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY\r
-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER\r
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\r
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\r
-THIS SOFTWARE.\r
-\r
-****************************************************************/\r
-\r
-/* Please send bug reports to David M. Gay (dmg at acm dot org,\r
- * with " at " changed at "@" and " dot " changed to "."). */\r
-#include <LibConfig.h>\r
-\r
-#include "gdtoaimp.h"\r
-\r
-/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.\r
- *\r
- * Inspired by "How to Print Floating-Point Numbers Accurately" by\r
- * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].\r
- *\r
- * Modifications:\r
- * 1. Rather than iterating, we use a simple numeric overestimate\r
- * to determine k = floor(log10(d)). We scale relevant\r
- * quantities using O(log2(k)) rather than O(k) multiplications.\r
- * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't\r
- * try to generate digits strictly left to right. Instead, we\r
- * compute with fewer bits and propagate the carry if necessary\r
- * when rounding the final digit up. This is often faster.\r
- * 3. Under the assumption that input will be rounded nearest,\r
- * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.\r
- * That is, we allow equality in stopping tests when the\r
- * round-nearest rule will give the same floating-point value\r
- * as would satisfaction of the stopping test with strict\r
- * inequality.\r
- * 4. We remove common factors of powers of 2 from relevant\r
- * quantities.\r
- * 5. When converting floating-point integers less than 1e16,\r
- * we use floating-point arithmetic rather than resorting\r
- * to multiple-precision integers.\r
- * 6. When asked to produce fewer than 15 digits, we first try\r
- * to get by with floating-point arithmetic; we resort to\r
- * multiple-precision integer arithmetic only if we cannot\r
- * guarantee that the floating-point calculation has given\r
- * the correctly rounded result. For k requested digits and\r
- * "uniformly" distributed input, the probability is\r
- * something like 10^(k-15) that we must resort to the Long\r
- * calculation.\r
- */\r
-\r
-#ifdef Honor_FLT_ROUNDS\r
-#define Rounding rounding\r
-#undef Check_FLT_ROUNDS\r
-#define Check_FLT_ROUNDS\r
-#else\r
-#define Rounding Flt_Rounds\r
-#endif\r
-\r
-#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */\r
-// Disable: warning C4700: uninitialized local variable 'xx' used\r
-#pragma warning ( disable : 4700 )\r
-#endif /* defined(_MSC_VER) */\r
-\r
- char *\r
-dtoa\r
-#ifdef KR_headers\r
- (d, mode, ndigits, decpt, sign, rve)\r
- double d; int mode, ndigits, *decpt, *sign; char **rve;\r
-#else\r
- (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)\r
-#endif\r
-{\r
- /* Arguments ndigits, decpt, sign are similar to those\r
- of ecvt and fcvt; trailing zeros are suppressed from\r
- the returned string. If not null, *rve is set to point\r
- to the end of the return value. If d is +-Infinity or NaN,\r
- then *decpt is set to 9999.\r
-\r
- mode:\r
- 0 ==> shortest string that yields d when read in\r
- and rounded to nearest.\r
- 1 ==> like 0, but with Steele & White stopping rule;\r
- e.g. with IEEE P754 arithmetic , mode 0 gives\r
- 1e23 whereas mode 1 gives 9.999999999999999e22.\r
- 2 ==> max(1,ndigits) significant digits. This gives a\r
- return value similar to that of ecvt, except\r
- that trailing zeros are suppressed.\r
- 3 ==> through ndigits past the decimal point. This\r
- gives a return value similar to that from fcvt,\r
- except that trailing zeros are suppressed, and\r
- ndigits can be negative.\r
- 4,5 ==> similar to 2 and 3, respectively, but (in\r
- round-nearest mode) with the tests of mode 0 to\r
- possibly return a shorter string that rounds to d.\r
- With IEEE arithmetic and compilation with\r
- -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same\r
- as modes 2 and 3 when FLT_ROUNDS != 1.\r
- 6-9 ==> Debugging modes similar to mode - 4: don't try\r
- fast floating-point estimate (if applicable).\r
-\r
- Values of mode other than 0-9 are treated as mode 0.\r
-\r
- Sufficient space is allocated to the return value\r
- to hold the suppressed trailing zeros.\r
- */\r
-\r
- int bbits, b2, b5, be, dig, i, ieps, ilim0,\r
- j, jj1, k, k0, k_check, leftright, m2, m5, s2, s5,\r
- spec_case, try_quick;\r
- int ilim = 0, ilim1 = 0; /* pacify gcc */\r
- Long L;\r
-#ifndef Sudden_Underflow\r
- int denorm;\r
- ULong x;\r
-#endif\r
- Bigint *b, *b1, *delta, *mhi, *S;\r
- Bigint *mlo = NULL; /* pacify gcc */\r
- double d2, ds, eps;\r
- char *s, *s0;\r
-#ifdef Honor_FLT_ROUNDS\r
- int rounding;\r
-#endif\r
-#ifdef SET_INEXACT\r
- int inexact, oldinexact;\r
-#endif\r
-\r
-#ifndef MULTIPLE_THREADS\r
- if (dtoa_result) {\r
- freedtoa(dtoa_result);\r
- dtoa_result = 0;\r
- }\r
-#endif\r
-\r
- if (word0(d) & Sign_bit) {\r
- /* set sign for everything, including 0's and NaNs */\r
- *sign = 1;\r
- word0(d) &= ~Sign_bit; /* clear sign bit */\r
- }\r
- else\r
- *sign = 0;\r
-\r
-#if defined(IEEE_Arith) + defined(VAX)\r
-#ifdef IEEE_Arith\r
- if ((word0(d) & Exp_mask) == Exp_mask)\r
-#else\r
- if (word0(d) == 0x8000)\r
-#endif\r
- {\r
- /* Infinity or NaN */\r
- *decpt = 9999;\r
-#ifdef IEEE_Arith\r
- if (!word1(d) && !(word0(d) & 0xfffff))\r
- return nrv_alloc("Infinity", rve, 8);\r
-#endif\r
- return nrv_alloc("NaN", rve, 3);\r
- }\r
-#endif\r
-#ifdef IBM\r
- dval(d) += 0; /* normalize */\r
-#endif\r
- if (!dval(d)) {\r
- *decpt = 1;\r
- return nrv_alloc("0", rve, 1);\r
- }\r
-\r
-#ifdef SET_INEXACT\r
- try_quick = oldinexact = get_inexact();\r
- inexact = 1;\r
-#endif\r
-#ifdef Honor_FLT_ROUNDS\r
- if ((rounding = Flt_Rounds) >= 2) {\r
- if (*sign)\r
- rounding = rounding == 2 ? 0 : 2;\r
- else\r
- if (rounding != 2)\r
- rounding = 0;\r
- }\r
-#endif\r
-\r
- b = d2b(dval(d), &be, &bbits);\r
- if (b == NULL)\r
- return NULL;\r
-#ifdef Sudden_Underflow\r
- i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));\r
-#else\r
- if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {\r
-#endif\r
- dval(d2) = dval(d);\r
- word0(d2) &= Frac_mask1;\r
- word0(d2) |= Exp_11;\r
-#ifdef IBM\r
- if (( j = 11 - hi0bits(word0(d2) & Frac_mask) )!=0)\r
- dval(d2) /= 1 << j;\r
-#endif\r
-\r
- /* log(x) ~=~ log(1.5) + (x-1.5)/1.5\r
- * log10(x) = log(x) / log(10)\r
- * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))\r
- * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)\r
- *\r
- * This suggests computing an approximation k to log10(d) by\r
- *\r
- * k = (i - Bias)*0.301029995663981\r
- * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );\r
- *\r
- * We want k to be too large rather than too small.\r
- * The error in the first-order Taylor series approximation\r
- * is in our favor, so we just round up the constant enough\r
- * to compensate for any error in the multiplication of\r
- * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,\r
- * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,\r
- * adding 1e-13 to the constant term more than suffices.\r
- * Hence we adjust the constant term to 0.1760912590558.\r
- * (We could get a more accurate k by invoking log10,\r
- * but this is probably not worthwhile.)\r
- */\r
-\r
- i -= Bias;\r
-#ifdef IBM\r
- i <<= 2;\r
- i += j;\r
-#endif\r
-#ifndef Sudden_Underflow\r
- denorm = 0;\r
- }\r
- else {\r
- /* d is denormalized */\r
-\r
- i = bbits + be + (Bias + (P-1) - 1);\r
- x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)\r
- : word1(d) << (32 - i);\r
- dval(d2) = (double)x;\r
- word0(d2) -= 31*Exp_msk1; /* adjust exponent */\r
- i -= (Bias + (P-1) - 1) + 1;\r
- denorm = 1;\r
- }\r
-#endif\r
- ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;\r
- k = (int)ds;\r
- if (ds < 0. && ds != k)\r
- k--; /* want k = floor(ds) */\r
- k_check = 1;\r
- if (k >= 0 && k <= Ten_pmax) {\r
- if (dval(d) < tens[k])\r
- k--;\r
- k_check = 0;\r
- }\r
- j = bbits - i - 1;\r
- if (j >= 0) {\r
- b2 = 0;\r
- s2 = j;\r
- }\r
- else {\r
- b2 = -j;\r
- s2 = 0;\r
- }\r
- if (k >= 0) {\r
- b5 = 0;\r
- s5 = k;\r
- s2 += k;\r
- }\r
- else {\r
- b2 -= k;\r
- b5 = -k;\r
- s5 = 0;\r
- }\r
- if (mode < 0 || mode > 9)\r
- mode = 0;\r
-\r
-#ifndef SET_INEXACT\r
-#ifdef Check_FLT_ROUNDS\r
- try_quick = Rounding == 1;\r
-#else\r
- try_quick = 1;\r
-#endif\r
-#endif /*SET_INEXACT*/\r
-\r
- if (mode > 5) {\r
- mode -= 4;\r
- try_quick = 0;\r
- }\r
- leftright = 1;\r
- switch(mode) {\r
- case 0:\r
- case 1:\r
- ilim = ilim1 = -1;\r
- i = 18;\r
- ndigits = 0;\r
- break;\r
- case 2:\r
- leftright = 0;\r
- /* FALLTHROUGH */\r
- case 4:\r
- if (ndigits <= 0)\r
- ndigits = 1;\r
- ilim = ilim1 = i = ndigits;\r
- break;\r
- case 3:\r
- leftright = 0;\r
- /* FALLTHROUGH */\r
- case 5:\r
- i = ndigits + k + 1;\r
- ilim = i;\r
- ilim1 = i - 1;\r
- if (i <= 0)\r
- i = 1;\r
- }\r
- s = s0 = rv_alloc((size_t)i);\r
- if (s == NULL)\r
- return NULL;\r
-\r
-#ifdef Honor_FLT_ROUNDS\r
- if (mode > 1 && rounding != 1)\r
- leftright = 0;\r
-#endif\r
-\r
- if (ilim >= 0 && ilim <= Quick_max && try_quick) {\r
-\r
- /* Try to get by with floating-point arithmetic. */\r
-\r
- i = 0;\r
- dval(d2) = dval(d);\r
- k0 = k;\r
- ilim0 = ilim;\r
- ieps = 2; /* conservative */\r
- if (k > 0) {\r
- ds = tens[k&0xf];\r
- j = (unsigned int)k >> 4;\r
- if (j & Bletch) {\r
- /* prevent overflows */\r
- j &= Bletch - 1;\r
- dval(d) /= bigtens[n_bigtens-1];\r
- ieps++;\r
- }\r
- for(; j; j = (unsigned int)j >> 1, i++)\r
- if (j & 1) {\r
- ieps++;\r
- ds *= bigtens[i];\r
- }\r
- dval(d) /= ds;\r
- }\r
- else if (( jj1 = -k )!=0) {\r
- dval(d) *= tens[jj1 & 0xf];\r
- for(j = jj1 >> 4; j; j >>= 1, i++)\r
- if (j & 1) {\r
- ieps++;\r
- dval(d) *= bigtens[i];\r
- }\r
- }\r
- if (k_check && dval(d) < 1. && ilim > 0) {\r
- if (ilim1 <= 0)\r
- goto fast_failed;\r
- ilim = ilim1;\r
- k--;\r
- dval(d) *= 10.;\r
- ieps++;\r
- }\r
- dval(eps) = ieps*dval(d) + 7.;\r
- word0(eps) -= (P-1)*Exp_msk1;\r
- if (ilim == 0) {\r
- S = mhi = 0;\r
- dval(d) -= 5.;\r
- if (dval(d) > dval(eps))\r
- goto one_digit;\r
- if (dval(d) < -dval(eps))\r
- goto no_digits;\r
- goto fast_failed;\r
- }\r
-#ifndef No_leftright\r
- if (leftright) {\r
- /* Use Steele & White method of only\r
- * generating digits needed.\r
- */\r
- dval(eps) = 0.5/tens[ilim-1] - dval(eps);\r
- for(i = 0;;) {\r
- L = (INT32)dval(d);\r
- dval(d) -= L;\r
- *s++ = (char)('0' + (int)L);\r
- if (dval(d) < dval(eps))\r
- goto ret1;\r
- if (1. - dval(d) < dval(eps))\r
- goto bump_up;\r
- if (++i >= ilim)\r
- break;\r
- dval(eps) *= 10.;\r
- dval(d) *= 10.;\r
- }\r
- }\r
- else {\r
-#endif\r
- /* Generate ilim digits, then fix them up. */\r
- dval(eps) *= tens[ilim-1];\r
- for(i = 1;; i++, dval(d) *= 10.) {\r
- L = (Long)(dval(d));\r
- if (!(dval(d) -= L))\r
- ilim = i;\r
- *s++ = (char)('0' + (int)L);\r
- if (i == ilim) {\r
- if (dval(d) > 0.5 + dval(eps))\r
- goto bump_up;\r
- else if (dval(d) < 0.5 - dval(eps)) {\r
- while(*--s == '0');\r
- s++;\r
- goto ret1;\r
- }\r
- break;\r
- }\r
- }\r
-#ifndef No_leftright\r
- }\r
-#endif\r
- fast_failed:\r
- s = s0;\r
- dval(d) = dval(d2);\r
- k = k0;\r
- ilim = ilim0;\r
- }\r
-\r
- /* Do we have a "small" integer? */\r
-\r
- if (be >= 0 && k <= Int_max) {\r
- /* Yes. */\r
- ds = tens[k];\r
- if (ndigits < 0 && ilim <= 0) {\r
- S = mhi = 0;\r
- if (ilim < 0 || dval(d) <= 5*ds)\r
- goto no_digits;\r
- goto one_digit;\r
- }\r
- for(i = 1;; i++, dval(d) *= 10.) {\r
- L = (Long)(dval(d) / ds);\r
- dval(d) -= L*ds;\r
-#ifdef Check_FLT_ROUNDS\r
- /* If FLT_ROUNDS == 2, L will usually be high by 1 */\r
- if (dval(d) < 0) {\r
- L--;\r
- dval(d) += ds;\r
- }\r
-#endif\r
- *s++ = (char)('0' + (int)L);\r
- if (!dval(d)) {\r
-#ifdef SET_INEXACT\r
- inexact = 0;\r
-#endif\r
- break;\r
- }\r
- if (i == ilim) {\r
-#ifdef Honor_FLT_ROUNDS\r
- if (mode > 1)\r
- switch(rounding) {\r
- case 0: goto ret1;\r
- case 2: goto bump_up;\r
- }\r
-#endif\r
- dval(d) += dval(d);\r
- if (dval(d) > ds || (dval(d) == ds && L & 1)) {\r
- bump_up:\r
- while(*--s == '9')\r
- if (s == s0) {\r
- k++;\r
- *s = '0';\r
- break;\r
- }\r
- ++*s++;\r
- }\r
- break;\r
- }\r
- }\r
- goto ret1;\r
- }\r
-\r
- m2 = b2;\r
- m5 = b5;\r
- mhi = mlo = 0;\r
- if (leftright) {\r
- i =\r
-#ifndef Sudden_Underflow\r
- denorm ? be + (Bias + (P-1) - 1 + 1) :\r
-#endif\r
-#ifdef IBM\r
- 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);\r
-#else\r
- 1 + P - bbits;\r
-#endif\r
- b2 += i;\r
- s2 += i;\r
- mhi = i2b(1);\r
- if (mhi == NULL)\r
- return NULL;\r
- }\r
- if (m2 > 0 && s2 > 0) {\r
- i = m2 < s2 ? m2 : s2;\r
- b2 -= i;\r
- m2 -= i;\r
- s2 -= i;\r
- }\r
- if (b5 > 0) {\r
- if (leftright) {\r
- if (m5 > 0) {\r
- mhi = pow5mult(mhi, m5);\r
- if (mhi == NULL)\r
- return NULL;\r
- b1 = mult(mhi, b);\r
- if (b1 == NULL)\r
- return NULL;\r
- Bfree(b);\r
- b = b1;\r
- }\r
- if (( j = b5 - m5 )!=0)\r
- b = pow5mult(b, j);\r
- if (b == NULL)\r
- return NULL;\r
- }\r
- else\r
- b = pow5mult(b, b5);\r
- if (b == NULL)\r
- return NULL;\r
- }\r
- S = i2b(1);\r
- if (S == NULL)\r
- return NULL;\r
- if (s5 > 0) {\r
- S = pow5mult(S, s5);\r
- if (S == NULL)\r
- return NULL;\r
- }\r
-\r
- /* Check for special case that d is a normalized power of 2. */\r
-\r
- spec_case = 0;\r
- if ((mode < 2 || leftright)\r
-#ifdef Honor_FLT_ROUNDS\r
- && rounding == 1\r
-#endif\r
- ) {\r
- if (!word1(d) && !(word0(d) & Bndry_mask)\r
-#ifndef Sudden_Underflow\r
- && word0(d) & (Exp_mask & ~Exp_msk1)\r
-#endif\r
- ) {\r
- /* The special case */\r
- b2 += Log2P;\r
- s2 += Log2P;\r
- spec_case = 1;\r
- }\r
- }\r
-\r
- /* Arrange for convenient computation of quotients:\r
- * shift left if necessary so divisor has 4 leading 0 bits.\r
- *\r
- * Perhaps we should just compute leading 28 bits of S once\r
- * and for all and pass them and a shift to quorem, so it\r
- * can do shifts and ors to compute the numerator for q.\r
- */\r
-#ifdef Pack_32\r
- if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0)\r
- i = 32 - i;\r
-#else\r
- if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0)\r
- i = 16 - i;\r
-#endif\r
- if (i > 4) {\r
- i -= 4;\r
- b2 += i;\r
- m2 += i;\r
- s2 += i;\r
- }\r
- else if (i < 4) {\r
- i += 28;\r
- b2 += i;\r
- m2 += i;\r
- s2 += i;\r
- }\r
- if (b2 > 0) {\r
- b = lshift(b, b2);\r
- if (b == NULL)\r
- return NULL;\r
- }\r
- if (s2 > 0) {\r
- S = lshift(S, s2);\r
- if (S == NULL)\r
- return NULL;\r
- }\r
- if (k_check) {\r
- if (cmp(b,S) < 0) {\r
- k--;\r
- b = multadd(b, 10, 0); /* we botched the k estimate */\r
- if (b == NULL)\r
- return NULL;\r
- if (leftright) {\r
- mhi = multadd(mhi, 10, 0);\r
- if (mhi == NULL)\r
- return NULL;\r
- }\r
- ilim = ilim1;\r
- }\r
- }\r
- if (ilim <= 0 && (mode == 3 || mode == 5)) {\r
- if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {\r
- /* no digits, fcvt style */\r
- no_digits:\r
- k = -1 - ndigits;\r
- goto ret;\r
- }\r
- one_digit:\r
- *s++ = '1';\r
- k++;\r
- goto ret;\r
- }\r
- if (leftright) {\r
- if (m2 > 0) {\r
- mhi = lshift(mhi, m2);\r
- if (mhi == NULL)\r
- return NULL;\r
- }\r
-\r
- /* Compute mlo -- check for special case\r
- * that d is a normalized power of 2.\r
- */\r
-\r
- mlo = mhi;\r
- if (spec_case) {\r
- mhi = Balloc(mhi->k);\r
- if (mhi == NULL)\r
- return NULL;\r
- Bcopy(mhi, mlo);\r
- mhi = lshift(mhi, Log2P);\r
- if (mhi == NULL)\r
- return NULL;\r
- }\r
-\r
- for(i = 1;;i++) {\r
- dig = quorem(b,S) + '0';\r
- /* Do we yet have the shortest decimal string\r
- * that will round to d?\r
- */\r
- j = cmp(b, mlo);\r
- delta = diff(S, mhi);\r
- if (delta == NULL)\r
- return NULL;\r
- jj1 = delta->sign ? 1 : cmp(b, delta);\r
- Bfree(delta);\r
-#ifndef ROUND_BIASED\r
- if (jj1 == 0 && mode != 1 && !(word1(d) & 1)\r
-#ifdef Honor_FLT_ROUNDS\r
- && rounding >= 1\r
-#endif\r
- ) {\r
- if (dig == '9')\r
- goto round_9_up;\r
- if (j > 0)\r
- dig++;\r
-#ifdef SET_INEXACT\r
- else if (!b->x[0] && b->wds <= 1)\r
- inexact = 0;\r
-#endif\r
- *s++ = (char)dig;\r
- goto ret;\r
- }\r
-#endif\r
- if (j < 0 || (j == 0 && mode != 1\r
-#ifndef ROUND_BIASED\r
- && !(word1(d) & 1)\r
-#endif\r
- )) {\r
- if (!b->x[0] && b->wds <= 1) {\r
-#ifdef SET_INEXACT\r
- inexact = 0;\r
-#endif\r
- goto accept_dig;\r
- }\r
-#ifdef Honor_FLT_ROUNDS\r
- if (mode > 1)\r
- switch(rounding) {\r
- case 0: goto accept_dig;\r
- case 2: goto keep_dig;\r
- }\r
-#endif /*Honor_FLT_ROUNDS*/\r
- if (jj1 > 0) {\r
- b = lshift(b, 1);\r
- if (b == NULL)\r
- return NULL;\r
- jj1 = cmp(b, S);\r
- if ((jj1 > 0 || (jj1 == 0 && dig & 1))\r
- && dig++ == '9')\r
- goto round_9_up;\r
- }\r
- accept_dig:\r
- *s++ = (char)dig;\r
- goto ret;\r
- }\r
- if (jj1 > 0) {\r
-#ifdef Honor_FLT_ROUNDS\r
- if (!rounding)\r
- goto accept_dig;\r
-#endif\r
- if (dig == '9') { /* possible if i == 1 */\r
- round_9_up:\r
- *s++ = '9';\r
- goto roundoff;\r
- }\r
- *s++ = (char)(dig + 1);\r
- goto ret;\r
- }\r
-#ifdef Honor_FLT_ROUNDS\r
- keep_dig:\r
-#endif\r
- *s++ = (char)dig;\r
- if (i == ilim)\r
- break;\r
- b = multadd(b, 10, 0);\r
- if (b == NULL)\r
- return NULL;\r
- if (mlo == mhi) {\r
- mlo = mhi = multadd(mhi, 10, 0);\r
- if (mlo == NULL)\r
- return NULL;\r
- }\r
- else {\r
- mlo = multadd(mlo, 10, 0);\r
- if (mlo == NULL)\r
- return NULL;\r
- mhi = multadd(mhi, 10, 0);\r
- if (mhi == NULL)\r
- return NULL;\r
- }\r
- }\r
- }\r
- else\r
- for(i = 1;; i++) {\r
- *s++ = (char)(dig = (int)(quorem(b,S) + '0'));\r
- if (!b->x[0] && b->wds <= 1) {\r
-#ifdef SET_INEXACT\r
- inexact = 0;\r
-#endif\r
- goto ret;\r
- }\r
- if (i >= ilim)\r
- break;\r
- b = multadd(b, 10, 0);\r
- if (b == NULL)\r
- return NULL;\r
- }\r
-\r
- /* Round off last digit */\r
-\r
-#ifdef Honor_FLT_ROUNDS\r
- switch(rounding) {\r
- case 0: goto trimzeros;\r
- case 2: goto roundoff;\r
- }\r
-#endif\r
- b = lshift(b, 1);\r
- j = cmp(b, S);\r
- if (j > 0 || (j == 0 && dig & 1)) {\r
- roundoff:\r
- while(*--s == '9')\r
- if (s == s0) {\r
- k++;\r
- *s++ = '1';\r
- goto ret;\r
- }\r
- ++*s++;\r
- }\r
- else {\r
-#ifdef Honor_FLT_ROUNDS\r
- trimzeros:\r
-#endif\r
- while(*--s == '0');\r
- s++;\r
- }\r
- ret:\r
- Bfree(S);\r
- if (mhi) {\r
- if (mlo && mlo != mhi)\r
- Bfree(mlo);\r
- Bfree(mhi);\r
- }\r
- ret1:\r
-#ifdef SET_INEXACT\r
- if (inexact) {\r
- if (!oldinexact) {\r
- word0(d) = Exp_1 + (70 << Exp_shift);\r
- word1(d) = 0;\r
- dval(d) += 1.;\r
- }\r
- }\r
- else if (!oldinexact)\r
- clear_inexact();\r
-#endif\r
- Bfree(b);\r
- if (s == s0) { /* don't return empty string */\r
- *s++ = '0';\r
- k = 0;\r
- }\r
- *s = 0;\r
- *decpt = k + 1;\r
- if (rve)\r
- *rve = s;\r
- return s0;\r
- }\r