gonzui


Format: Advanced Search

t2ex/bsd_source/lib/libc/src_bsd/stdlib/dtoa.cbare sourcepermlink (0.06 seconds)

Search this content:

    1: /****************************************************************
    2: 
    3: The author of this software is David M. Gay.
    4: 
    5: Copyright (C) 1998, 1999 by Lucent Technologies
    6: All Rights Reserved
    7: 
    8: Permission to use, copy, modify, and distribute this software and
    9: its documentation for any purpose and without fee is hereby
   10: granted, provided that the above copyright notice appear in all
   11: copies and that both that the copyright notice and this
   12: permission notice and warranty disclaimer appear in supporting
   13: documentation, and that the name of Lucent or any of its entities
   14: not be used in advertising or publicity pertaining to
   15: distribution of the software without specific, written prior
   16: permission.
   17: 
   18: LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
   19: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
   20: IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
   21: SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   22: WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
   23: IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
   24: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
   25: THIS SOFTWARE.
   26: 
   27: ****************************************************************/
   28: 
   29: /* Please send bug reports to David M. Gay (dmg at acm dot org,
   30:  * with " at " changed at "@" and " dot " changed to ".").      */
   31: 
   32: #include "gdtoaimp.h"
   33: 
   34: /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
   35:  *
   36:  * Inspired by "How to Print Floating-Point Numbers Accurately" by
   37:  * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
   38:  *
   39:  * Modifications:
   40:  *      1. Rather than iterating, we use a simple numeric overestimate
   41:  *         to determine k = floor(log10(d)).  We scale relevant
   42:  *         quantities using O(log2(k)) rather than O(k) multiplications.
   43:  *      2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
   44:  *         try to generate digits strictly left to right.  Instead, we
   45:  *         compute with fewer bits and propagate the carry if necessary
   46:  *         when rounding the final digit up.  This is often faster.
   47:  *      3. Under the assumption that input will be rounded nearest,
   48:  *         mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
   49:  *         That is, we allow equality in stopping tests when the
   50:  *         round-nearest rule will give the same floating-point value
   51:  *         as would satisfaction of the stopping test with strict
   52:  *         inequality.
   53:  *      4. We remove common factors of powers of 2 from relevant
   54:  *         quantities.
   55:  *      5. When converting floating-point integers less than 1e16,
   56:  *         we use floating-point arithmetic rather than resorting
   57:  *         to multiple-precision integers.
   58:  *      6. When asked to produce fewer than 15 digits, we first try
   59:  *         to get by with floating-point arithmetic; we resort to
   60:  *         multiple-precision integer arithmetic only if we cannot
   61:  *         guarantee that the floating-point calculation has given
   62:  *         the correctly rounded result.  For k requested digits and
   63:  *         "uniformly" distributed input, the probability is
   64:  *         something like 10^(k-15) that we must resort to the Long
   65:  *         calculation.
   66:  */
   67: 
   68: #ifdef Honor_FLT_ROUNDS
   69: #undef Check_FLT_ROUNDS
   70: #define Check_FLT_ROUNDS
   71: #else
   72: #define Rounding Flt_Rounds
   73: #endif
   74: 
   75:  char *
   76: dtoa
   77: #ifdef KR_headers
   78:         (d0, mode, ndigits, decpt, sign, rve)
   79:         double d0; int mode, ndigits, *decpt, *sign; char **rve;
   80: #else
   81:         (double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
   82: #endif
   83: {
   84:  /*     Arguments ndigits, decpt, sign are similar to those
   85:         of ecvt and fcvt; trailing zeros are suppressed from
   86:         the returned string.  If not null, *rve is set to point
   87:         to the end of the return value.  If d is +-Infinity or NaN,
   88:         then *decpt is set to 9999.
   89: 
   90:         mode:
   91:                 0 ==> shortest string that yields d when read in
   92:                         and rounded to nearest.
   93:                 1 ==> like 0, but with Steele & White stopping rule;
   94:                         e.g. with IEEE P754 arithmetic , mode 0 gives
   95:                         1e23 whereas mode 1 gives 9.999999999999999e22.
   96:                 2 ==> max(1,ndigits) significant digits.  This gives a
   97:                         return value similar to that of ecvt, except
   98:                         that trailing zeros are suppressed.
   99:                 3 ==> through ndigits past the decimal point.  This
  100:                         gives a return value similar to that from fcvt,
  101:                         except that trailing zeros are suppressed, and
  102:                         ndigits can be negative.
  103:                 4,5 ==> similar to 2 and 3, respectively, but (in
  104:                         round-nearest mode) with the tests of mode 0 to
  105:                         possibly return a shorter string that rounds to d.
  106:                         With IEEE arithmetic and compilation with
  107:                         -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
  108:                         as modes 2 and 3 when FLT_ROUNDS != 1.
  109:                 6-9 ==> Debugging modes similar to mode - 4:  don't try
  110:                         fast floating-point estimate (if applicable).
  111: 
  112:                 Values of mode other than 0-9 are treated as mode 0.
  113: 
  114:                 Sufficient space is allocated to the return value
  115:                 to hold the suppressed trailing zeros.
  116:         */
  117: 
  118:         int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
  119:                 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
  120:                 spec_case, try_quick;
  121:         Long L;
  122: #ifndef Sudden_Underflow
  123:         int denorm;
  124:         ULong x;
  125: #endif
  126:         Bigint *b, *b1, *delta, *mlo, *mhi, *S;
  127:         U d, d2, eps;
  128:         double ds;
  129:         char *s, *s0;
  130: #ifdef SET_INEXACT
  131:         int inexact, oldinexact;
  132: #endif
  133: #ifdef Honor_FLT_ROUNDS /*{*/
  134:         int Rounding;
  135: #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
  136:         Rounding = Flt_Rounds;
  137: #else /*}{*/
  138:         Rounding = 1;
  139:         switch(fegetround()) {
  140:           case FE_TOWARDZERO:  Rounding = 0; break;
  141:           case FE_UPWARD:      Rounding = 2; break;
  142:           case FE_DOWNWARD:    Rounding = 3;
  143:           }
  144: #endif /*}}*/
  145: #endif /*}*/
  146: 
  147: #ifndef MULTIPLE_THREADS
  148:         if (dtoa_result) {
  149:                 freedtoa(dtoa_result);
  150:                 dtoa_result = 0;
  151:                 }
  152: #endif
  153:         d.d = d0;
  154:         if (word0(&d) & Sign_bit) {
  155:                 /* set sign for everything, including 0's and NaNs */
  156:                 *sign = 1;
  157:                 word0(&d) &= ~Sign_bit;       /* clear sign bit */
  158:                 }
  159:         else
  160:                 *sign = 0;
  161: 
  162: #if defined(IEEE_Arith) + defined(VAX)
  163: #ifdef IEEE_Arith
  164:         if ((word0(&d) & Exp_mask) == Exp_mask)
  165: #else
  166:         if (word0(&d)  == 0x8000)
  167: #endif
  168:                 {
  169:                 /* Infinity or NaN */
  170:                 *decpt = 9999;
  171: #ifdef IEEE_Arith
  172:                 if (!word1(&d) && !(word0(&d) & 0xfffff))
  173:                         return nrv_alloc("Infinity", rve, 8);
  174: #endif
  175:                 return nrv_alloc("NaN", rve, 3);
  176:                 }
  177: #endif
  178: #ifdef IBM
  179:         dval(&d) += 0; /* normalize */
  180: #endif
  181:         if (!dval(&d)) {
  182:                 *decpt = 1;
  183:                 return nrv_alloc("0", rve, 1);
  184:                 }
  185: 
  186: #ifdef SET_INEXACT
  187:         try_quick = oldinexact = get_inexact();
  188:         inexact = 1;
  189: #endif
  190: #ifdef Honor_FLT_ROUNDS
  191:         if (Rounding >= 2) {
  192:                 if (*sign)
  193:                         Rounding = Rounding == 2 ? 0 : 2;
  194:                 else
  195:                         if (Rounding != 2)
  196:                                 Rounding = 0;
  197:                 }
  198: #endif
  199: 
  200:         b = d2b(dval(&d), &be, &bbits);
  201:         if (b == NULL)
  202:                 return (NULL);
  203: #ifdef Sudden_Underflow
  204:         i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
  205: #else
  206:         if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {
  207: #endif
  208:                 dval(&d2) = dval(&d);
  209:                 word0(&d2) &= Frac_mask1;
  210:                 word0(&d2) |= Exp_11;
  211: #ifdef IBM
  212:                 if (( j = 11 - hi0bits(word0(&d2) & Frac_mask) )!=0)
  213:                         dval(&d2) /= 1 << j;
  214: #endif
  215: 
  216:                 /* log(x)     ~=~ log(1.5) + (x-1.5)/1.5
  217:                  * log10(x)    =  log(x) / log(10)
  218:                  *            ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
  219:                  * log10(&d) = (i-Bias)*log(2)/log(10) + log10(&d2)
  220:                  *
  221:                  * This suggests computing an approximation k to log10(&d) by
  222:                  *
  223:                  * k = (i - Bias)*0.301029995663981
  224:                  *    + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
  225:                  *
  226:                  * We want k to be too large rather than too small.
  227:                  * The error in the first-order Taylor series approximation
  228:                  * is in our favor, so we just round up the constant enough
  229:                  * to compensate for any error in the multiplication of
  230:                  * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
  231:                  * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
  232:                  * adding 1e-13 to the constant term more than suffices.
  233:                  * Hence we adjust the constant term to 0.1760912590558.
  234:                  * (We could get a more accurate k by invoking log10,
  235:                  *  but this is probably not worthwhile.)
  236:                  */
  237: 
  238:                 i -= Bias;
  239: #ifdef IBM
  240:                 i <<= 2;
  241:                 i += j;
  242: #endif
  243: #ifndef Sudden_Underflow
  244:                 denorm = 0;
  245:                 }
  246:         else {
  247:                 /* d is denormalized */
  248: 
  249:                 i = bbits + be + (Bias + (P-1) - 1);
  250:                 x = i > 32  ? word0(&d) << (64 - i) | word1(&d) >> (i - 32)
  251:                             : word1(&d) << (32 - i);
  252:                 dval(&d2) = x;
  253:                 word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
  254:                 i -= (Bias + (P-1) - 1) + 1;
  255:                 denorm = 1;
  256:                 }
  257: #endif
  258:         ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
  259:         k = (int)ds;
  260:         if (ds < 0. && ds != k)
  261:                 k--;  /* want k = floor(ds) */
  262:         k_check = 1;
  263:         if (k >= 0 && k <= Ten_pmax) {
  264:                 if (dval(&d) < tens[k])
  265:                         k--;
  266:                 k_check = 0;
  267:                 }
  268:         j = bbits - i - 1;
  269:         if (j >= 0) {
  270:                 b2 = 0;
  271:                 s2 = j;
  272:                 }
  273:         else {
  274:                 b2 = -j;
  275:                 s2 = 0;
  276:                 }
  277:         if (k >= 0) {
  278:                 b5 = 0;
  279:                 s5 = k;
  280:                 s2 += k;
  281:                 }
  282:         else {
  283:                 b2 -= k;
  284:                 b5 = -k;
  285:                 s5 = 0;
  286:                 }
  287:         if (mode < 0 || mode > 9)
  288:                 mode = 0;
  289: 
  290: #ifndef SET_INEXACT
  291: #ifdef Check_FLT_ROUNDS
  292:         try_quick = Rounding == 1;
  293: #else
  294:         try_quick = 1;
  295: #endif
  296: #endif /*SET_INEXACT*/
  297: 
  298:         if (mode > 5) {
  299:                 mode -= 4;
  300:                 try_quick = 0;
  301:                 }
  302:         leftright = 1;
  303:         ilim = ilim1 = -1;     /* Values for cases 0 and 1; done here to */
  304:                                 /* silence erroneous "gcc -Wall" warning. */
  305:         switch(mode) {
  306:                 case 0:
  307:                 case 1:
  308:                         i = 18;
  309:                         ndigits = 0;
  310:                         break;
  311:                 case 2:
  312:                         leftright = 0;
  313:                         /* no break */
  314:                 case 4:
  315:                         if (ndigits <= 0)
  316:                                 ndigits = 1;
  317:                         ilim = ilim1 = i = ndigits;
  318:                         break;
  319:                 case 3:
  320:                         leftright = 0;
  321:                         /* no break */
  322:                 case 5:
  323:                         i = ndigits + k + 1;
  324:                         ilim = i;
  325:                         ilim1 = i - 1;
  326:                         if (i <= 0)
  327:                                 i = 1;
  328:                 }
  329:         s = s0 = rv_alloc(i);
  330:         if (s == NULL)
  331:                 return (NULL);
  332: 
  333: #ifdef Honor_FLT_ROUNDS
  334:         if (mode > 1 && Rounding != 1)
  335:                 leftright = 0;
  336: #endif
  337: 
  338:         if (ilim >= 0 && ilim <= Quick_max && try_quick) {
  339: 
  340:                 /* Try to get by with floating-point arithmetic. */
  341: 
  342:                 i = 0;
  343:                 dval(&d2) = dval(&d);
  344:                 k0 = k;
  345:                 ilim0 = ilim;
  346:                 ieps = 2; /* conservative */
  347:                 if (k > 0) {
  348:                         ds = tens[k&0xf];
  349:                         j = k >> 4;
  350:                         if (j & Bletch) {
  351:                                 /* prevent overflows */
  352:                                 j &= Bletch - 1;
  353:                                 dval(&d) /= bigtens[n_bigtens-1];
  354:                                 ieps++;
  355:                                 }
  356:                         for(; j; j >>= 1, i++)
  357:                                 if (j & 1) {
  358:                                         ieps++;
  359:                                         ds *= bigtens[i];
  360:                                         }
  361:                         dval(&d) /= ds;
  362:                         }
  363:                 else if (( j1 = -k )!=0) {
  364:                         dval(&d) *= tens[j1 & 0xf];
  365:                         for(j = j1 >> 4; j; j >>= 1, i++)
  366:                                 if (j & 1) {
  367:                                         ieps++;
  368:                                         dval(&d) *= bigtens[i];
  369:                                         }
  370:                         }
  371:                 if (k_check && dval(&d) < 1. && ilim > 0) {
  372:                         if (ilim1 <= 0)
  373:                                 goto fast_failed;
  374:                         ilim = ilim1;
  375:                         k--;
  376:                         dval(&d) *= 10.;
  377:                         ieps++;
  378:                         }
  379:                 dval(&eps) = ieps*dval(&d) + 7.;
  380:                 word0(&eps) -= (P-1)*Exp_msk1;
  381:                 if (ilim == 0) {
  382:                         S = mhi = 0;
  383:                         dval(&d) -= 5.;
  384:                         if (dval(&d) > dval(&eps))
  385:                                 goto one_digit;
  386:                         if (dval(&d) < -dval(&eps))
  387:                                 goto no_digits;
  388:                         goto fast_failed;
  389:                         }
  390: #ifndef No_leftright
  391:                 if (leftright) {
  392:                         /* Use Steele & White method of only
  393:                          * generating digits needed.
  394:                          */
  395:                         dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
  396:                         for(i = 0;;) {
  397:                                 L = dval(&d);
  398:                                 dval(&d) -= L;
  399:                                 *s++ = '0' + (int)L;
  400:                                 if (dval(&d) < dval(&eps))
  401:                                         goto ret1;
  402:                                 if (1. - dval(&d) < dval(&eps))
  403:                                         goto bump_up;
  404:                                 if (++i >= ilim)
  405:                                         break;
  406:                                 dval(&eps) *= 10.;
  407:                                 dval(&d) *= 10.;
  408:                                 }
  409:                         }
  410:                 else {
  411: #endif
  412:                         /* Generate ilim digits, then fix them up. */
  413:                         dval(&eps) *= tens[ilim-1];
  414:                         for(i = 1;; i++, dval(&d) *= 10.) {
  415:                                 L = (Long)(dval(&d));
  416:                                 if (!(dval(&d) -= L))
  417:                                         ilim = i;
  418:                                 *s++ = '0' + (int)L;
  419:                                 if (i == ilim) {
  420:                                         if (dval(&d) > 0.5 + dval(&eps))
  421:                                                 goto bump_up;
  422:                                         else if (dval(&d) < 0.5 - dval(&eps)) {
  423:                                                 while(*--s == '0');
  424:                                                 s++;
  425:                                                 goto ret1;
  426:                                                 }
  427:                                         break;
  428:                                         }
  429:                                 }
  430: #ifndef No_leftright
  431:                         }
  432: #endif
  433:  fast_failed:
  434:                 s = s0;
  435:                 dval(&d) = dval(&d2);
  436:                 k = k0;
  437:                 ilim = ilim0;
  438:                 }
  439: 
  440:         /* Do we have a "small" integer? */
  441: 
  442:         if (be >= 0 && k <= Int_max) {
  443:                 /* Yes. */
  444:                 ds = tens[k];
  445:                 if (ndigits < 0 && ilim <= 0) {
  446:                         S = mhi = 0;
  447:                         if (ilim < 0 || dval(&d) <= 5*ds)
  448:                                 goto no_digits;
  449:                         goto one_digit;
  450:                         }
  451:                 for(i = 1;; i++, dval(&d) *= 10.) {
  452:                         L = (Long)(dval(&d) / ds);
  453:                         dval(&d) -= L*ds;
  454: #ifdef Check_FLT_ROUNDS
  455:                         /* If FLT_ROUNDS == 2, L will usually be high by 1 */
  456:                         if (dval(&d) < 0) {
  457:                                 L--;
  458:                                 dval(&d) += ds;
  459:                                 }
  460: #endif
  461:                         *s++ = '0' + (int)L;
  462:                         if (!dval(&d)) {
  463: #ifdef SET_INEXACT
  464:                                 inexact = 0;
  465: #endif
  466:                                 break;
  467:                                 }
  468:                         if (i == ilim) {
  469: #ifdef Honor_FLT_ROUNDS
  470:                                 if (mode > 1)
  471:                                 switch(Rounding) {
  472:                                   case 0: goto ret1;
  473:                                   case 2: goto bump_up;
  474:                                   }
  475: #endif
  476:                                 dval(&d) += dval(&d);
  477: #ifdef ROUND_BIASED
  478:                                 if (dval(&d) >= ds)
  479: #else
  480:                                 if (dval(&d) > ds || (dval(&d) == ds && L & 1))
  481: #endif
  482:                                         {
  483:  bump_up:
  484:                                         while(*--s == '9')
  485:                                                 if (s == s0) {
  486:                                                         k++;
  487:                                                         *s = '0';
  488:                                                         break;
  489:                                                         }
  490:                                         ++*s++;
  491:                                         }
  492:                                 break;
  493:                                 }
  494:                         }
  495:                 goto ret1;
  496:                 }
  497: 
  498:         m2 = b2;
  499:         m5 = b5;
  500:         mhi = mlo = 0;
  501:         if (leftright) {
  502:                 i =
  503: #ifndef Sudden_Underflow
  504:                         denorm ? be + (Bias + (P-1) - 1 + 1) :
  505: #endif
  506: #ifdef IBM
  507:                         1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
  508: #else
  509:                         1 + P - bbits;
  510: #endif
  511:                 b2 += i;
  512:                 s2 += i;
  513:                 mhi = i2b(1);
  514:                 if (mhi == NULL)
  515:                         return (NULL);
  516:                 }
  517:         if (m2 > 0 && s2 > 0) {
  518:                 i = m2 < s2 ? m2 : s2;
  519:                 b2 -= i;
  520:                 m2 -= i;
  521:                 s2 -= i;
  522:                 }
  523:         if (b5 > 0) {
  524:                 if (leftright) {
  525:                         if (m5 > 0) {
  526:                                 mhi = pow5mult(mhi, m5);
  527:                                 if (mhi == NULL)
  528:                                         return (NULL);
  529:                                 b1 = mult(mhi, b);
  530:                                 if (b1 == NULL)
  531:                                         return (NULL);
  532:                                 Bfree(b);
  533:                                 b = b1;
  534:                                 }
  535:                         if (( j = b5 - m5 )!=0) {
  536:                                 b = pow5mult(b, j);
  537:                                 if (b == NULL)
  538:                                         return (NULL);
  539:                                 }
  540:                         }
  541:                 else {
  542:                         b = pow5mult(b, b5);
  543:                         if (b == NULL)
  544:                                 return (NULL);
  545:                         }
  546:                 }
  547:         S = i2b(1);
  548:         if (S == NULL)
  549:                 return (NULL);
  550:         if (s5 > 0) {
  551:                 S = pow5mult(S, s5);
  552:                 if (S == NULL)
  553:                         return (NULL);
  554:                 }
  555: 
  556:         /* Check for special case that d is a normalized power of 2. */
  557: 
  558:         spec_case = 0;
  559:         if ((mode < 2 || leftright)
  560: #ifdef Honor_FLT_ROUNDS
  561:                         && Rounding == 1
  562: #endif
  563:                                 ) {
  564:                 if (!word1(&d) && !(word0(&d) & Bndry_mask)
  565: #ifndef Sudden_Underflow
  566:                  && word0(&d) & (Exp_mask & ~Exp_msk1)
  567: #endif
  568:                                 ) {
  569:                         /* The special case */
  570:                         b2 += Log2P;
  571:                         s2 += Log2P;
  572:                         spec_case = 1;
  573:                         }
  574:                 }
  575: 
  576:         /* Arrange for convenient computation of quotients:
  577:          * shift left if necessary so divisor has 4 leading 0 bits.
  578:          *
  579:          * Perhaps we should just compute leading 28 bits of S once
  580:          * and for all and pass them and a shift to quorem, so it
  581:          * can do shifts and ors to compute the numerator for q.
  582:          */
  583: #ifdef Pack_32
  584:         if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0)
  585:                 i = 32 - i;
  586: #else
  587:         if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0)
  588:                 i = 16 - i;
  589: #endif
  590:         if (i > 4) {
  591:                 i -= 4;
  592:                 b2 += i;
  593:                 m2 += i;
  594:                 s2 += i;
  595:                 }
  596:         else if (i < 4) {
  597:                 i += 28;
  598:                 b2 += i;
  599:                 m2 += i;
  600:                 s2 += i;
  601:                 }
  602:         if (b2 > 0) {
  603:                 b = lshift(b, b2);
  604:                 if (b == NULL)
  605:                         return (NULL);
  606:                 }
  607:         if (s2 > 0) {
  608:                 S = lshift(S, s2);
  609:                 if (S == NULL)
  610:                         return (NULL);
  611:                 }
  612:         if (k_check) {
  613:                 if (cmp(b,S) < 0) {
  614:                         k--;
  615:                         b = multadd(b, 10, 0);       /* we botched the k estimate */
  616:                         if (b == NULL)
  617:                                 return (NULL);
  618:                         if (leftright) {
  619:                                 mhi = multadd(mhi, 10, 0);
  620:                                 if (mhi == NULL)
  621:                                         return (NULL);
  622:                                 }
  623:                         ilim = ilim1;
  624:                         }
  625:                 }
  626:         if (ilim <= 0 && (mode == 3 || mode == 5)) {
  627:                 S = multadd(S,5,0);
  628:                 if (S == NULL)
  629:                         return (NULL);
  630:                 if (ilim < 0 || cmp(b,S) <= 0) {
  631:                         /* no digits, fcvt style */
  632:  no_digits:
  633:                         k = -1 - ndigits;
  634:                         goto ret;
  635:                         }
  636:  one_digit:
  637:                 *s++ = '1';
  638:                 k++;
  639:                 goto ret;
  640:                 }
  641:         if (leftright) {
  642:                 if (m2 > 0) {
  643:                         mhi = lshift(mhi, m2);
  644:                         if (mhi == NULL)
  645:                                 return (NULL);
  646:                         }
  647: 
  648:                 /* Compute mlo -- check for special case
  649:                  * that d is a normalized power of 2.
  650:                  */
  651: 
  652:                 mlo = mhi;
  653:                 if (spec_case) {
  654:                         mhi = Balloc(mhi->k);
  655:                         if (mhi == NULL)
  656:                                 return (NULL);
  657:                         Bcopy(mhi, mlo);
  658:                         mhi = lshift(mhi, Log2P);
  659:                         if (mhi == NULL)
  660:                                 return (NULL);
  661:                         }
  662: 
  663:                 for(i = 1;;i++) {
  664:                         dig = quorem(b,S) + '0';
  665:                         /* Do we yet have the shortest decimal string
  666:                          * that will round to d?
  667:                          */
  668:                         j = cmp(b, mlo);
  669:                         delta = diff(S, mhi);
  670:                         if (delta == NULL)
  671:                                 return (NULL);
  672:                         j1 = delta->sign ? 1 : cmp(b, delta);
  673:                         Bfree(delta);
  674: #ifndef ROUND_BIASED
  675:                         if (j1 == 0 && mode != 1 && !(word1(&d) & 1)
  676: #ifdef Honor_FLT_ROUNDS
  677:                                 && Rounding >= 1
  678: #endif
  679:                                                                    ) {
  680:                                 if (dig == '9')
  681:                                         goto round_9_up;
  682:                                 if (j > 0)
  683:                                         dig++;
  684: #ifdef SET_INEXACT
  685:                                 else if (!b->x[0] && b->wds <= 1)
  686:                                         inexact = 0;
  687: #endif
  688:                                 *s++ = dig;
  689:                                 goto ret;
  690:                                 }
  691: #endif
  692:                         if (j < 0 || (j == 0 && mode != 1
  693: #ifndef ROUND_BIASED
  694:                                                         && !(word1(&d) & 1)
  695: #endif
  696:                                         )) {
  697:                                 if (!b->x[0] && b->wds <= 1) {
  698: #ifdef SET_INEXACT
  699:                                         inexact = 0;
  700: #endif
  701:                                         goto accept_dig;
  702:                                         }
  703: #ifdef Honor_FLT_ROUNDS
  704:                                 if (mode > 1)
  705:                                  switch(Rounding) {
  706:                                   case 0: goto accept_dig;
  707:                                   case 2: goto keep_dig;
  708:                                   }
  709: #endif /*Honor_FLT_ROUNDS*/
  710:                                 if (j1 > 0) {
  711:                                         b = lshift(b, 1);
  712:                                         if (b == NULL)
  713:                                                 return (NULL);
  714:                                         j1 = cmp(b, S);
  715: #ifdef ROUND_BIASED
  716:                                         if (j1 >= 0 /*)*/
  717: #else
  718:                                         if ((j1 > 0 || (j1 == 0 && dig & 1))
  719: #endif
  720:                                         && dig++ == '9')
  721:                                                 goto round_9_up;
  722:                                         }
  723:  accept_dig:
  724:                                 *s++ = dig;
  725:                                 goto ret;
  726:                                 }
  727:                         if (j1 > 0) {
  728: #ifdef Honor_FLT_ROUNDS
  729:                                 if (!Rounding)
  730:                                         goto accept_dig;
  731: #endif
  732:                                 if (dig == '9') { /* possible if i == 1 */
  733:  round_9_up:
  734:                                         *s++ = '9';
  735:                                         goto roundoff;
  736:                                         }
  737:                                 *s++ = dig + 1;
  738:                                 goto ret;
  739:                                 }
  740: #ifdef Honor_FLT_ROUNDS
  741:  keep_dig:
  742: #endif
  743:                         *s++ = dig;
  744:                         if (i == ilim)
  745:                                 break;
  746:                         b = multadd(b, 10, 0);
  747:                         if (b == NULL)
  748:                                 return (NULL);
  749:                         if (mlo == mhi) {
  750:                                 mlo = mhi = multadd(mhi, 10, 0);
  751:                                 if (mlo == NULL)
  752:                                         return (NULL);
  753:                                 }
  754:                         else {
  755:                                 mlo = multadd(mlo, 10, 0);
  756:                                 if (mlo == NULL)
  757:                                         return (NULL);
  758:                                 mhi = multadd(mhi, 10, 0);
  759:                                 if (mhi == NULL)
  760:                                         return (NULL);
  761:                                 }
  762:                         }
  763:                 }
  764:         else
  765:                 for(i = 1;; i++) {
  766:                         *s++ = dig = quorem(b,S) + '0';
  767:                         if (!b->x[0] && b->wds <= 1) {
  768: #ifdef SET_INEXACT
  769:                                 inexact = 0;
  770: #endif
  771:                                 goto ret;
  772:                                 }
  773:                         if (i >= ilim)
  774:                                 break;
  775:                         b = multadd(b, 10, 0);
  776:                         if (b == NULL)
  777:                                 return (NULL);
  778:                         }
  779: 
  780:         /* Round off last digit */
  781: 
  782: #ifdef Honor_FLT_ROUNDS
  783:         switch(Rounding) {
  784:           case 0: goto trimzeros;
  785:           case 2: goto roundoff;
  786:           }
  787: #endif
  788:         b = lshift(b, 1);
  789:         if (b == NULL)
  790:                 return (NULL);
  791:         j = cmp(b, S);
  792: #ifdef ROUND_BIASED
  793:         if (j >= 0)
  794: #else
  795:         if (j > 0 || (j == 0 && dig & 1))
  796: #endif
  797:                 {
  798:  roundoff:
  799:                 while(*--s == '9')
  800:                         if (s == s0) {
  801:                                 k++;
  802:                                 *s++ = '1';
  803:                                 goto ret;
  804:                                 }
  805:                 ++*s++;
  806:                 }
  807:         else {
  808: #ifdef Honor_FLT_ROUNDS
  809:  trimzeros:
  810: #endif
  811:                 while(*--s == '0');
  812:                 s++;
  813:                 }
  814:  ret:
  815:         Bfree(S);
  816:         if (mhi) {
  817:                 if (mlo && mlo != mhi)
  818:                         Bfree(mlo);
  819:                 Bfree(mhi);
  820:                 }
  821:  ret1:
  822: #ifdef SET_INEXACT
  823:         if (inexact) {
  824:                 if (!oldinexact) {
  825:                         word0(&d) = Exp_1 + (70 << Exp_shift);
  826:                         word1(&d) = 0;
  827:                         dval(&d) += 1.;
  828:                         }
  829:                 }
  830:         else if (!oldinexact)
  831:                 clear_inexact();
  832: #endif
  833:         Bfree(b);
  834:         *s = 0;
  835:         *decpt = k + 1;
  836:         if (rve)
  837:                 *rve = s;
  838:         return s0;
  839:         }