+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials are licensed and made available under\r
- the terms and conditions of the BSD License that accompanies this distribution.\r
- The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\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
- Please send bug reports to David M. Gay (dmg at acm dot org,\r
- with " at " changed at "@" and " dot " changed to ".").\r
-\r
- NetBSD: gdtoa.c,v 1.1.1.1.4.1.4.1 2008/04/08 21:10:55 jdc Exp\r
-**/\r
-#include <LibConfig.h>\r
-\r
-#include "gdtoaimp.h"\r
-\r
-#if defined(_MSC_VER)\r
- /* Disable warnings about conversions to narrower data types. */\r
- #pragma warning ( disable : 4244 )\r
- // Squelch bogus warnings about uninitialized variable use.\r
- #pragma warning ( disable : 4701 )\r
-#endif\r
-\r
-static Bigint *\r
-bitstob(ULong *bits, int nbits, int *bbits)\r
-{\r
- int i, k;\r
- Bigint *b;\r
- ULong *be, *x, *x0;\r
-\r
- i = ULbits;\r
- k = 0;\r
- while(i < nbits) {\r
- i <<= 1;\r
- k++;\r
- }\r
-#ifndef Pack_32\r
- if (!k)\r
- k = 1;\r
-#endif\r
- b = Balloc(k);\r
- if (b == NULL)\r
- return NULL;\r
- be = bits + (((unsigned int)nbits - 1) >> kshift);\r
- x = x0 = b->x;\r
- do {\r
- *x++ = *bits & ALL_ON;\r
-#ifdef Pack_16\r
- *x++ = (*bits >> 16) & ALL_ON;\r
-#endif\r
- } while(++bits <= be);\r
- i = x - x0;\r
- while(!x0[--i])\r
- if (!i) {\r
- b->wds = 0;\r
- *bbits = 0;\r
- goto ret;\r
- }\r
- b->wds = i + 1;\r
- *bbits = i*ULbits + 32 - hi0bits(b->x[i]);\r
-ret:\r
- return b;\r
-}\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
- char *\r
-gdtoa\r
- (FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)\r
-{\r
- /* Arguments ndigits and decpt are similar to the second and third\r
- arguments 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-9 should give the same return values as 2-3, i.e.,\r
- 4 <= mode <= 9 ==> same return as mode\r
- 2 + (mode & 1). These modes are mainly for\r
- debugging; often they run slower but sometimes\r
- faster than modes 2-3.\r
- 4,5,8,9 ==> left-to-right digit generation.\r
- 6-9 ==> don't try fast floating-point estimate\r
- (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, be0, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, inex;\r
- int j, jj1, k, k0, k_check, kind, leftright, m2, m5, nbits;\r
- int rdir, s2, s5, spec_case, try_quick;\r
- Long L;\r
- Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S;\r
- double d, d2, ds, eps;\r
- char *s, *s0;\r
-\r
- mlo = NULL;\r
-\r
-#ifndef MULTIPLE_THREADS\r
- if (dtoa_result) {\r
- freedtoa(dtoa_result);\r
- dtoa_result = 0;\r
- }\r
-#endif\r
- inex = 0;\r
- if (*kindp & STRTOG_NoMemory)\r
- return NULL;\r
- kind = *kindp &= ~STRTOG_Inexact;\r
- switch(kind & STRTOG_Retmask) {\r
- case STRTOG_Zero:\r
- goto ret_zero;\r
- case STRTOG_Normal:\r
- case STRTOG_Denormal:\r
- break;\r
- case STRTOG_Infinite:\r
- *decpt = -32768;\r
- return nrv_alloc("Infinity", rve, 8);\r
- case STRTOG_NaN:\r
- *decpt = -32768;\r
- return nrv_alloc("NaN", rve, 3);\r
- default:\r
- return 0;\r
- }\r
- b = bitstob(bits, nbits = fpi->nbits, &bbits);\r
- if (b == NULL)\r
- return NULL;\r
- be0 = be;\r
- if ( (i = trailz(b)) !=0) {\r
- rshift(b, i);\r
- be += i;\r
- bbits -= i;\r
- }\r
- if (!b->wds) {\r
- Bfree(b);\r
-ret_zero:\r
- *decpt = 1;\r
- return nrv_alloc("0", rve, 1);\r
- }\r
-\r
- dval(d) = b2d(b, &i);\r
- i = be + bbits - 1;\r
- word0(d) &= Frac_mask1;\r
- word0(d) |= Exp_11;\r
-#ifdef IBM\r
- if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)\r
- dval(d) /= 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
-#ifdef IBM\r
- i <<= 2;\r
- i += j;\r
-#endif\r
- ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;\r
-\r
- /* correct assumption about exponent range */\r
- if ((j = i) < 0)\r
- j = -j;\r
- if ((j -= 1077) > 0)\r
- ds += j * 7e-17;\r
-\r
- k = (int)ds;\r
- if (ds < 0. && ds != k)\r
- k--; /* want k = floor(ds) */\r
- k_check = 1;\r
-#ifdef IBM\r
- j = be + bbits - 1;\r
- if ( (jj1 = j & 3) !=0)\r
- dval(d) *= 1 << jj1;\r
- word0(d) += j << Exp_shift - 2 & Exp_mask;\r
-#else\r
- word0(d) += (be + bbits - 1) << Exp_shift;\r
-#endif\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
- try_quick = 1;\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 = (int)(nbits * .30103) + 3;\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
- if ( (rdir = fpi->rounding - 1) !=0) {\r
- if (rdir < 0)\r
- rdir = 2;\r
- if (kind & STRTOG_Neg)\r
- rdir = 3 - rdir;\r
- }\r
-\r
- /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */\r
-\r
- if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir\r
-#ifndef IMPRECISE_INEXACT\r
- && k == 0\r
-#endif\r
- ) {\r
-\r
- /* Try to get by with floating-point arithmetic. */\r
-\r
- i = 0;\r
- d2 = dval(d);\r
-#ifdef IBM\r
- if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)\r
- dval(d) /= 1 << j;\r
-#endif\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 /= 2, i++)\r
- if (j & 1) {\r
- ieps++;\r
- ds *= bigtens[i];\r
- }\r
- }\r
- else {\r
- ds = 1.;\r
- 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
- }\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) = ds*0.5/tens[ilim-1] - dval(eps);\r
- for(i = 0;;) {\r
- L = (Long)(dval(d)/ds);\r
- dval(d) -= L*ds;\r
- *s++ = '0' + (int)L;\r
- if (dval(d) < dval(eps)) {\r
- if (dval(d))\r
- inex = STRTOG_Inexlo;\r
- goto ret1;\r
- }\r
- if (ds - 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
- if ( (L = (Long)(dval(d)/ds)) !=0)\r
- dval(d) -= L*ds;\r
- *s++ = '0' + (int)L;\r
- if (i == ilim) {\r
- ds *= 0.5;\r
- if (dval(d) > ds + dval(eps))\r
- goto bump_up;\r
- else if (dval(d) < ds - dval(eps)) {\r
- while(*--s == '0'){}\r
- s++;\r
- if (dval(d))\r
- inex = STRTOG_Inexlo;\r
- goto ret1;\r
- }\r
- break;\r
- }\r
- }\r
-#ifndef No_leftright\r
- }\r
-#endif\r
-fast_failed:\r
- s = s0;\r
- dval(d) = 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 = 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++ = '0' + (int)L;\r
- if (dval(d) == 0.)\r
- break;\r
- if (i == ilim) {\r
- if (rdir) {\r
- if (rdir == 1)\r
- goto bump_up;\r
- inex = STRTOG_Inexlo;\r
- goto ret1;\r
- }\r
- dval(d) += dval(d);\r
- if (dval(d) > ds || (dval(d) == ds && L & 1)) {\r
-bump_up:\r
- inex = STRTOG_Inexhi;\r
- while(*--s == '9')\r
- if (s == s0) {\r
- k++;\r
- *s = '0';\r
- break;\r
- }\r
- ++*s++;\r
- }\r
- else\r
- inex = STRTOG_Inexlo;\r
- break;\r
- }\r
- }\r
- goto ret1;\r
- }\r
-\r
- m2 = b2;\r
- m5 = b5;\r
- mhi = NULL;\r
- mlo = NULL;\r
- if (leftright) {\r
- if (mode < 2) {\r
- i = nbits - bbits;\r
- if (be - i++ < fpi->emin)\r
- /* denormal */\r
- i = be - fpi->emin + 1;\r
- }\r
- else {\r
- j = ilim - 1;\r
- if (m5 >= j)\r
- m5 -= j;\r
- else {\r
- s5 += j -= m5;\r
- b5 += j;\r
- m5 = 0;\r
- }\r
- if ((i = ilim) < 0) {\r
- m2 -= i;\r
- i = 0;\r
- }\r
- }\r
- b2 += i;\r
- s2 += i;\r
- mhi = i2b(1);\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
- }\r
- else {\r
- b = pow5mult(b, b5);\r
- if (b == NULL)\r
- return NULL;\r
- }\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) {\r
- if (bbits == 1 && be0 > fpi->emin + 1) {\r
- /* The special case */\r
- b2++;\r
- s2++;\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 (s2 > 0)\r
- S = lshift(S, s2);\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 > 2) {\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
- inex = STRTOG_Inexlo;\r
- goto ret;\r
- }\r
-one_digit:\r
- inex = STRTOG_Inexhi;\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, 1);\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 && !(bits[0] & 1) && !rdir) {\r
- if (dig == '9')\r
- goto round_9_up;\r
- if (j <= 0) {\r
- if (b->wds > 1 || b->x[0])\r
- inex = STRTOG_Inexlo;\r
- }\r
- else {\r
- dig++;\r
- inex = STRTOG_Inexhi;\r
- }\r
- *s++ = dig;\r
- goto ret;\r
- }\r
-#endif\r
- if (j < 0 || (j == 0 && !mode\r
-#ifndef ROUND_BIASED\r
- && !(bits[0] & 1)\r
-#endif\r
- )) {\r
- if (rdir && (b->wds > 1 || b->x[0])) {\r
- if (rdir == 2) {\r
- inex = STRTOG_Inexlo;\r
- goto accept;\r
- }\r
- while (cmp(S,mhi) > 0) {\r
- *s++ = dig;\r
- mhi1 = multadd(mhi, 10, 0);\r
- if (mhi1 == NULL)\r
- return NULL;\r
- if (mlo == mhi)\r
- mlo = mhi1;\r
- mhi = mhi1;\r
- b = multadd(b, 10, 0);\r
- if (b == NULL)\r
- return NULL;\r
- dig = quorem(b,S) + '0';\r
- }\r
- if (dig++ == '9')\r
- goto round_9_up;\r
- inex = STRTOG_Inexhi;\r
- goto accept;\r
- }\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
- inex = STRTOG_Inexhi;\r
- }\r
- if (b->wds > 1 || b->x[0])\r
- inex = STRTOG_Inexlo;\r
-accept:\r
- *s++ = dig;\r
- goto ret;\r
- }\r
- if (jj1 > 0 && rdir != 2) {\r
- if (dig == '9') { /* possible if i == 1 */\r
-round_9_up:\r
- *s++ = '9';\r
- inex = STRTOG_Inexhi;\r
- goto roundoff;\r
- }\r
- inex = STRTOG_Inexhi;\r
- *s++ = dig + 1;\r
- goto ret;\r
- }\r
- *s++ = 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++ = dig = quorem(b,S) + '0';\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
- if (rdir) {\r
- if (rdir == 2 || (b->wds <= 1 && !b->x[0]))\r
- goto chopzeros;\r
- goto roundoff;\r
- }\r
- b = lshift(b, 1);\r
- if (b == NULL)\r
- return NULL;\r
- j = cmp(b, S);\r
- if (j > 0 || (j == 0 && dig & 1)) {\r
-roundoff:\r
- inex = STRTOG_Inexhi;\r
- while(*--s == '9')\r
- if (s == s0) {\r
- k++;\r
- *s++ = '1';\r
- goto ret;\r
- }\r
- ++*s++;\r
- }\r
- else {\r
-chopzeros:\r
- if (b->wds > 1 || b->x[0])\r
- inex = STRTOG_Inexlo;\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
- Bfree(b);\r
- *s = 0;\r
- *decpt = k + 1;\r
- if (rve)\r
- *rve = s;\r
- *kindp |= inex;\r
- return s0;\r
-}\r