]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/LibC/gdtoa/dtoa.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / StdLib / LibC / gdtoa / dtoa.c
diff --git a/StdLib/LibC/gdtoa/dtoa.c b/StdLib/LibC/gdtoa/dtoa.c
deleted file mode 100644 (file)
index cd3b1c8..0000000
+++ /dev/null
@@ -1,821 +0,0 @@
-/* $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