gonzui


Format: Advanced Search

t2ex/bsd_source/lib/libc/src_bsd/stdlib/gdtoa.cbare sourcepermlink (0.05 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:  static Bigint *
   35: #ifdef KR_headers
   36: bitstob(bits, nbits, bbits) ULong *bits; int nbits; int *bbits;
   37: #else
   38: bitstob(ULong *bits, int nbits, int *bbits)
   39: #endif
   40: {
   41:         int i, k;
   42:         Bigint *b;
   43:         ULong *be, *x, *x0;
   44: 
   45:         i = ULbits;
   46:         k = 0;
   47:         while(i < nbits) {
   48:                 i <<= 1;
   49:                 k++;
   50:                 }
   51: #ifndef Pack_32
   52:         if (!k)
   53:                 k = 1;
   54: #endif
   55:         b = Balloc(k);
   56:         if (b == NULL)
   57:                 return (NULL);
   58:         be = bits + ((nbits - 1) >> kshift);
   59:         x = x0 = b->x;
   60:         do {
   61:                 *x++ = *bits & ALL_ON;
   62: #ifdef Pack_16
   63:                 *x++ = (*bits >> 16) & ALL_ON;
   64: #endif
   65:                 } while(++bits <= be);
   66:         i = x - x0;
   67:         while(!x0[--i])
   68:                 if (!i) {
   69:                         b->wds = 0;
   70:                         *bbits = 0;
   71:                         goto ret;
   72:                         }
   73:         b->wds = i + 1;
   74:         *bbits = i*ULbits + 32 - hi0bits(b->x[i]);
   75:  ret:
   76:         return b;
   77:         }
   78: 
   79: /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
   80:  *
   81:  * Inspired by "How to Print Floating-Point Numbers Accurately" by
   82:  * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
   83:  *
   84:  * Modifications:
   85:  *      1. Rather than iterating, we use a simple numeric overestimate
   86:  *         to determine k = floor(log10(d)).  We scale relevant
   87:  *         quantities using O(log2(k)) rather than O(k) multiplications.
   88:  *      2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
   89:  *         try to generate digits strictly left to right.  Instead, we
   90:  *         compute with fewer bits and propagate the carry if necessary
   91:  *         when rounding the final digit up.  This is often faster.
   92:  *      3. Under the assumption that input will be rounded nearest,
   93:  *         mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
   94:  *         That is, we allow equality in stopping tests when the
   95:  *         round-nearest rule will give the same floating-point value
   96:  *         as would satisfaction of the stopping test with strict
   97:  *         inequality.
   98:  *      4. We remove common factors of powers of 2 from relevant
   99:  *         quantities.
  100:  *      5. When converting floating-point integers less than 1e16,
  101:  *         we use floating-point arithmetic rather than resorting
  102:  *         to multiple-precision integers.
  103:  *      6. When asked to produce fewer than 15 digits, we first try
  104:  *         to get by with floating-point arithmetic; we resort to
  105:  *         multiple-precision integer arithmetic only if we cannot
  106:  *         guarantee that the floating-point calculation has given
  107:  *         the correctly rounded result.  For k requested digits and
  108:  *         "uniformly" distributed input, the probability is
  109:  *         something like 10^(k-15) that we must resort to the Long
  110:  *         calculation.
  111:  */
  112: 
  113:  char *
  114: gdtoa
  115: #ifdef KR_headers
  116:         (fpi, be, bits, kindp, mode, ndigits, decpt, rve)
  117:         FPI *fpi; int be; ULong *bits;
  118:         int *kindp, mode, ndigits, *decpt; char **rve;
  119: #else
  120:         (FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
  121: #endif
  122: {
  123:  /*     Arguments ndigits and decpt are similar to the second and third
  124:         arguments of ecvt and fcvt; trailing zeros are suppressed from
  125:         the returned string.  If not null, *rve is set to point
  126:         to the end of the return value.  If d is +-Infinity or NaN,
  127:         then *decpt is set to 9999.
  128:         be = exponent: value = (integer represented by bits) * (2 to the power of be).
  129: 
  130:         mode:
  131:                 0 ==> shortest string that yields d when read in
  132:                         and rounded to nearest.
  133:                 1 ==> like 0, but with Steele & White stopping rule;
  134:                         e.g. with IEEE P754 arithmetic , mode 0 gives
  135:                         1e23 whereas mode 1 gives 9.999999999999999e22.
  136:                 2 ==> max(1,ndigits) significant digits.  This gives a
  137:                         return value similar to that of ecvt, except
  138:                         that trailing zeros are suppressed.
  139:                 3 ==> through ndigits past the decimal point.  This
  140:                         gives a return value similar to that from fcvt,
  141:                         except that trailing zeros are suppressed, and
  142:                         ndigits can be negative.
  143:                 4-9 should give the same return values as 2-3, i.e.,
  144:                         4 <= mode <= 9 ==> same return as mode
  145:                         2 + (mode & 1).  These modes are mainly for
  146:                         debugging; often they run slower but sometimes
  147:                         faster than modes 2-3.
  148:                 4,5,8,9 ==> left-to-right digit generation.
  149:                 6-9 ==> don't try fast floating-point estimate
  150:                         (if applicable).
  151: 
  152:                 Values of mode other than 0-9 are treated as mode 0.
  153: 
  154:                 Sufficient space is allocated to the return value
  155:                 to hold the suppressed trailing zeros.
  156:         */
  157: 
  158:         int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex;
  159:         int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits;
  160:         int rdir, s2, s5, spec_case, try_quick;
  161:         Long L;
  162:         Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S;
  163:         double d2, ds;
  164:         char *s, *s0;
  165:         U d, eps;
  166: 
  167: #ifndef MULTIPLE_THREADS
  168:         if (dtoa_result) {
  169:                 freedtoa(dtoa_result);
  170:                 dtoa_result = 0;
  171:                 }
  172: #endif
  173:         inex = 0;
  174:         kind = *kindp &= ~STRTOG_Inexact;
  175:         switch(kind & STRTOG_Retmask) {
  176:           case STRTOG_Zero:
  177:                 goto ret_zero;
  178:           case STRTOG_Normal:
  179:           case STRTOG_Denormal:
  180:                 break;
  181:           case STRTOG_Infinite:
  182:                 *decpt = -32768;
  183:                 return nrv_alloc("Infinity", rve, 8);
  184:           case STRTOG_NaN:
  185:                 *decpt = -32768;
  186:                 return nrv_alloc("NaN", rve, 3);
  187:           default:
  188:                 return 0;
  189:           }
  190:         b = bitstob(bits, nbits = fpi->nbits, &bbits);
  191:         if (b == NULL)
  192:                 return (NULL);
  193:         be0 = be;
  194:         if ( (i = trailz(b)) !=0) {
  195:                 rshift(b, i);
  196:                 be += i;
  197:                 bbits -= i;
  198:                 }
  199:         if (!b->wds) {
  200:                 Bfree(b);
  201:  ret_zero:
  202:                 *decpt = 1;
  203:                 return nrv_alloc("0", rve, 1);
  204:                 }
  205: 
  206:         dval(&d) = b2d(b, &i);
  207:         i = be + bbits - 1;
  208:         word0(&d) &= Frac_mask1;
  209:         word0(&d) |= Exp_11;
  210: #ifdef IBM
  211:         if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0)
  212:                 dval(&d) /= 1 << j;
  213: #endif
  214: 
  215:         /* log(x)      ~=~ log(1.5) + (x-1.5)/1.5
  216:          * log10(x)     =  log(x) / log(10)
  217:          *             ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
  218:          * log10(&d) = (i-Bias)*log(2)/log(10) + log10(d2)
  219:          *
  220:          * This suggests computing an approximation k to log10(&d) by
  221:          *
  222:          * k = (i - Bias)*0.301029995663981
  223:          *     + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
  224:          *
  225:          * We want k to be too large rather than too small.
  226:          * The error in the first-order Taylor series approximation
  227:          * is in our favor, so we just round up the constant enough
  228:          * to compensate for any error in the multiplication of
  229:          * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
  230:          * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
  231:          * adding 1e-13 to the constant term more than suffices.
  232:          * Hence we adjust the constant term to 0.1760912590558.
  233:          * (We could get a more accurate k by invoking log10,
  234:          *  but this is probably not worthwhile.)
  235:          */
  236: #ifdef IBM
  237:         i <<= 2;
  238:         i += j;
  239: #endif
  240:         ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
  241: 
  242:         /* correct assumption about exponent range */
  243:         if ((j = i) < 0)
  244:                 j = -j;
  245:         if ((j -= 1077) > 0)
  246:                 ds += j * 7e-17;
  247: 
  248:         k = (int)ds;
  249:         if (ds < 0. && ds != k)
  250:                 k--;  /* want k = floor(ds) */
  251:         k_check = 1;
  252: #ifdef IBM
  253:         j = be + bbits - 1;
  254:         if ( (j1 = j & 3) !=0)
  255:                 dval(&d) *= 1 << j1;
  256:         word0(&d) += j << Exp_shift - 2 & Exp_mask;
  257: #else
  258:         word0(&d) += (be + bbits - 1) << Exp_shift;
  259: #endif
  260:         if (k >= 0 && k <= Ten_pmax) {
  261:                 if (dval(&d) < tens[k])
  262:                         k--;
  263:                 k_check = 0;
  264:                 }
  265:         j = bbits - i - 1;
  266:         if (j >= 0) {
  267:                 b2 = 0;
  268:                 s2 = j;
  269:                 }
  270:         else {
  271:                 b2 = -j;
  272:                 s2 = 0;
  273:                 }
  274:         if (k >= 0) {
  275:                 b5 = 0;
  276:                 s5 = k;
  277:                 s2 += k;
  278:                 }
  279:         else {
  280:                 b2 -= k;
  281:                 b5 = -k;
  282:                 s5 = 0;
  283:                 }
  284:         if (mode < 0 || mode > 9)
  285:                 mode = 0;
  286:         try_quick = 1;
  287:         if (mode > 5) {
  288:                 mode -= 4;
  289:                 try_quick = 0;
  290:                 }
  291:         else if (i >= -4 - Emin || i < Emin)
  292:                 try_quick = 0;
  293:         leftright = 1;
  294:         ilim = ilim1 = -1;     /* Values for cases 0 and 1; done here to */
  295:                                 /* silence erroneous "gcc -Wall" warning. */
  296:         switch(mode) {
  297:                 case 0:
  298:                 case 1:
  299:                         i = (int)(nbits * .30103) + 3;
  300:                         ndigits = 0;
  301:                         break;
  302:                 case 2:
  303:                         leftright = 0;
  304:                         /* no break */
  305:                 case 4:
  306:                         if (ndigits <= 0)
  307:                                 ndigits = 1;
  308:                         ilim = ilim1 = i = ndigits;
  309:                         break;
  310:                 case 3:
  311:                         leftright = 0;
  312:                         /* no break */
  313:                 case 5:
  314:                         i = ndigits + k + 1;
  315:                         ilim = i;
  316:                         ilim1 = i - 1;
  317:                         if (i <= 0)
  318:                                 i = 1;
  319:                 }
  320:         s = s0 = rv_alloc(i);
  321:         if (s == NULL)
  322:                 return (NULL);
  323: 
  324:         if ( (rdir = fpi->rounding - 1) !=0) {
  325:                 if (rdir < 0)
  326:                         rdir = 2;
  327:                 if (kind & STRTOG_Neg)
  328:                         rdir = 3 - rdir;
  329:                 }
  330: 
  331:         /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */
  332: 
  333:         if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir
  334: #ifndef IMPRECISE_INEXACT
  335:                 && k == 0
  336: #endif
  337:                                                                 ) {
  338: 
  339:                 /* Try to get by with floating-point arithmetic. */
  340: 
  341:                 i = 0;
  342:                 d2 = dval(&d);
  343: #ifdef IBM
  344:                 if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0)
  345:                         dval(&d) /= 1 << j;
  346: #endif
  347:                 k0 = k;
  348:                 ilim0 = ilim;
  349:                 ieps = 2; /* conservative */
  350:                 if (k > 0) {
  351:                         ds = tens[k&0xf];
  352:                         j = k >> 4;
  353:                         if (j & Bletch) {
  354:                                 /* prevent overflows */
  355:                                 j &= Bletch - 1;
  356:                                 dval(&d) /= bigtens[n_bigtens-1];
  357:                                 ieps++;
  358:                                 }
  359:                         for(; j; j >>= 1, i++)
  360:                                 if (j & 1) {
  361:                                         ieps++;
  362:                                         ds *= bigtens[i];
  363:                                         }
  364:                         }
  365:                 else  {
  366:                         ds = 1.;
  367:                         if ( (j1 = -k) !=0) {
  368:                                 dval(&d) *= tens[j1 & 0xf];
  369:                                 for(j = j1 >> 4; j; j >>= 1, i++)
  370:                                         if (j & 1) {
  371:                                                 ieps++;
  372:                                                 dval(&d) *= bigtens[i];
  373:                                                 }
  374:                                 }
  375:                         }
  376:                 if (k_check && dval(&d) < 1. && ilim > 0) {
  377:                         if (ilim1 <= 0)
  378:                                 goto fast_failed;
  379:                         ilim = ilim1;
  380:                         k--;
  381:                         dval(&d) *= 10.;
  382:                         ieps++;
  383:                         }
  384:                 dval(&eps) = ieps*dval(&d) + 7.;
  385:                 word0(&eps) -= (P-1)*Exp_msk1;
  386:                 if (ilim == 0) {
  387:                         S = mhi = 0;
  388:                         dval(&d) -= 5.;
  389:                         if (dval(&d) > dval(&eps))
  390:                                 goto one_digit;
  391:                         if (dval(&d) < -dval(&eps))
  392:                                 goto no_digits;
  393:                         goto fast_failed;
  394:                         }
  395: #ifndef No_leftright
  396:                 if (leftright) {
  397:                         /* Use Steele & White method of only
  398:                          * generating digits needed.
  399:                          */
  400:                         dval(&eps) = ds*0.5/tens[ilim-1] - dval(&eps);
  401:                         for(i = 0;;) {
  402:                                 L = (Long)(dval(&d)/ds);
  403:                                 dval(&d) -= L*ds;
  404:                                 *s++ = '0' + (int)L;
  405:                                 if (dval(&d) < dval(&eps)) {
  406:                                         if (dval(&d))
  407:                                                 inex = STRTOG_Inexlo;
  408:                                         goto ret1;
  409:                                         }
  410:                                 if (ds - dval(&d) < dval(&eps))
  411:                                         goto bump_up;
  412:                                 if (++i >= ilim)
  413:                                         break;
  414:                                 dval(&eps) *= 10.;
  415:                                 dval(&d) *= 10.;
  416:                                 }
  417:                         }
  418:                 else {
  419: #endif
  420:                         /* Generate ilim digits, then fix them up. */
  421:                         dval(&eps) *= tens[ilim-1];
  422:                         for(i = 1;; i++, dval(&d) *= 10.) {
  423:                                 if ( (L = (Long)(dval(&d)/ds)) !=0)
  424:                                         dval(&d) -= L*ds;
  425:                                 *s++ = '0' + (int)L;
  426:                                 if (i == ilim) {
  427:                                         ds *= 0.5;
  428:                                         if (dval(&d) > ds + dval(&eps))
  429:                                                 goto bump_up;
  430:                                         else if (dval(&d) < ds - dval(&eps)) {
  431:                                                 if (dval(&d))
  432:                                                         inex = STRTOG_Inexlo;
  433:                                                 goto clear_trailing0;
  434:                                                 }
  435:                                         break;
  436:                                         }
  437:                                 }
  438: #ifndef No_leftright
  439:                         }
  440: #endif
  441:  fast_failed:
  442:                 s = s0;
  443:                 dval(&d) = d2;
  444:                 k = k0;
  445:                 ilim = ilim0;
  446:                 }
  447: 
  448:         /* Do we have a "small" integer? */
  449: 
  450:         if (be >= 0 && k <= Int_max) {
  451:                 /* Yes. */
  452:                 ds = tens[k];
  453:                 if (ndigits < 0 && ilim <= 0) {
  454:                         S = mhi = 0;
  455:                         if (ilim < 0 || dval(&d) <= 5*ds)
  456:                                 goto no_digits;
  457:                         goto one_digit;
  458:                         }
  459:                 for(i = 1;; i++, dval(&d) *= 10.) {
  460:                         L = dval(&d) / ds;
  461:                         dval(&d) -= L*ds;
  462: #ifdef Check_FLT_ROUNDS
  463:                         /* If FLT_ROUNDS == 2, L will usually be high by 1 */
  464:                         if (dval(&d) < 0) {
  465:                                 L--;
  466:                                 dval(&d) += ds;
  467:                                 }
  468: #endif
  469:                         *s++ = '0' + (int)L;
  470:                         if (dval(&d) == 0.)
  471:                                 break;
  472:                         if (i == ilim) {
  473:                                 if (rdir) {
  474:                                         if (rdir == 1)
  475:                                                 goto bump_up;
  476:                                         inex = STRTOG_Inexlo;
  477:                                         goto ret1;
  478:                                         }
  479:                                 dval(&d) += dval(&d);
  480: #ifdef ROUND_BIASED
  481:                                 if (dval(&d) >= ds)
  482: #else
  483:                                 if (dval(&d) > ds || (dval(&d) == ds && L & 1))
  484: #endif
  485:                                         {
  486:  bump_up:
  487:                                         inex = STRTOG_Inexhi;
  488:                                         while(*--s == '9')
  489:                                                 if (s == s0) {
  490:                                                         k++;
  491:                                                         *s = '0';
  492:                                                         break;
  493:                                                         }
  494:                                         ++*s++;
  495:                                         }
  496:                                 else {
  497:                                         inex = STRTOG_Inexlo;
  498:  clear_trailing0:
  499:                                         while(*--s == '0'){}
  500:                                         ++s;
  501:                                         }
  502:                                 break;
  503:                                 }
  504:                         }
  505:                 goto ret1;
  506:                 }
  507: 
  508:         m2 = b2;
  509:         m5 = b5;
  510:         mhi = mlo = 0;
  511:         if (leftright) {
  512:                 i = nbits - bbits;
  513:                 if (be - i++ < fpi->emin && mode != 3 && mode != 5) {
  514:                         /* denormal */
  515:                         i = be - fpi->emin + 1;
  516:                         if (mode >= 2 && ilim > 0 && ilim < i)
  517:                                 goto small_ilim;
  518:                         }
  519:                 else if (mode >= 2) {
  520:  small_ilim:
  521:                         j = ilim - 1;
  522:                         if (m5 >= j)
  523:                                 m5 -= j;
  524:                         else {
  525:                                 s5 += j -= m5;
  526:                                 b5 += j;
  527:                                 m5 = 0;
  528:                                 }
  529:                         if ((i = ilim) < 0) {
  530:                                 m2 -= i;
  531:                                 i = 0;
  532:                                 }
  533:                         }
  534:                 b2 += i;
  535:                 s2 += i;
  536:                 mhi = i2b(1);
  537:                 if (mhi == NULL)
  538:                         return (NULL);
  539:                 }
  540:         if (m2 > 0 && s2 > 0) {
  541:                 i = m2 < s2 ? m2 : s2;
  542:                 b2 -= i;
  543:                 m2 -= i;
  544:                 s2 -= i;
  545:                 }
  546:         if (b5 > 0) {
  547:                 if (leftright) {
  548:                         if (m5 > 0) {
  549:                                 mhi = pow5mult(mhi, m5);
  550:                                 if (mhi == NULL)
  551:                                         return (NULL);
  552:                                 b1 = mult(mhi, b);
  553:                                 if (b1 == NULL)
  554:                                         return (NULL);
  555:                                 Bfree(b);
  556:                                 b = b1;
  557:                                 }
  558:                         if ( (j = b5 - m5) !=0) {
  559:                                 b = pow5mult(b, j);
  560:                                 if (b == NULL)
  561:                                         return (NULL);
  562:                                 }
  563:                         }
  564:                 else {
  565:                         b = pow5mult(b, b5);
  566:                         if (b == NULL)
  567:                                 return (NULL);
  568:                         }
  569:                 }
  570:         S = i2b(1);
  571:         if (S == NULL)
  572:                 return (NULL);
  573:         if (s5 > 0) {
  574:                 S = pow5mult(S, s5);
  575:                 if (S == NULL)
  576:                         return (NULL);
  577:                 }
  578: 
  579:         /* Check for special case that d is a normalized power of 2. */
  580: 
  581:         spec_case = 0;
  582:         if (mode < 2) {
  583:                 if (bbits == 1 && be0 > fpi->emin + 1) {
  584:                         /* The special case */
  585:                         b2++;
  586:                         s2++;
  587:                         spec_case = 1;
  588:                         }
  589:                 }
  590: 
  591:         /* Arrange for convenient computation of quotients:
  592:          * shift left if necessary so divisor has 4 leading 0 bits.
  593:          *
  594:          * Perhaps we should just compute leading 28 bits of S once
  595:          * and for all and pass them and a shift to quorem, so it
  596:          * can do shifts and ors to compute the numerator for q.
  597:          */
  598:         i = ((s5 ? hi0bits(S->x[S->wds-1]) : ULbits - 1) - s2 - 4) & kmask;
  599:         m2 += i;
  600:         if ((b2 += i) > 0) {
  601:                 b = lshift(b, b2);
  602:                 if (b == NULL)
  603:                         return (NULL);
  604:                 }
  605:         if ((s2 += i) > 0) {
  606:                 S = lshift(S, s2);
  607:                 if (S == NULL)
  608:                         return (NULL);
  609:                 }
  610:         if (k_check) {
  611:                 if (cmp(b,S) < 0) {
  612:                         k--;
  613:                         b = multadd(b, 10, 0);       /* we botched the k estimate */
  614:                         if (b == NULL)
  615:                                 return (NULL);
  616:                         if (leftright) {
  617:                                 mhi = multadd(mhi, 10, 0);
  618:                                 if (mhi == NULL)
  619:                                         return (NULL);
  620:                                 }
  621:                         ilim = ilim1;
  622:                         }
  623:                 }
  624:         if (ilim <= 0 && mode > 2) {
  625:                 S = multadd(S,5,0);
  626:                 if (S == NULL)
  627:                         return (NULL);
  628:                 if (ilim < 0 || cmp(b,S) <= 0) {
  629:                         /* no digits, fcvt style */
  630:  no_digits:
  631:                         k = -1 - ndigits;
  632:                         inex = STRTOG_Inexlo;
  633:                         goto ret;
  634:                         }
  635:  one_digit:
  636:                 inex = STRTOG_Inexhi;
  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, 1);
  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 && !(bits[0] & 1) && !rdir) {
  676:                                 if (dig == '9')
  677:                                         goto round_9_up;
  678:                                 if (j <= 0) {
  679:                                         if (b->wds > 1 || b->x[0])
  680:                                                 inex = STRTOG_Inexlo;
  681:                                         }
  682:                                 else {
  683:                                         dig++;
  684:                                         inex = STRTOG_Inexhi;
  685:                                         }
  686:                                 *s++ = dig;
  687:                                 goto ret;
  688:                                 }
  689: #endif
  690:                         if (j < 0 || (j == 0 && !mode
  691: #ifndef ROUND_BIASED
  692:                                                         && !(bits[0] & 1)
  693: #endif
  694:                                         )) {
  695:                                 if (rdir && (b->wds > 1 || b->x[0])) {
  696:                                         if (rdir == 2) {
  697:                                                 inex = STRTOG_Inexlo;
  698:                                                 goto accept;
  699:                                                 }
  700:                                         while (cmp(S,mhi) > 0) {
  701:                                                 *s++ = dig;
  702:                                                 mhi1 = multadd(mhi, 10, 0);
  703:                                                 if (mhi1 == NULL)
  704:                                                         return (NULL);
  705:                                                 if (mlo == mhi)
  706:                                                         mlo = mhi1;
  707:                                                 mhi = mhi1;
  708:                                                 b = multadd(b, 10, 0);
  709:                                                 if (b == NULL)
  710:                                                         return (NULL);
  711:                                                 dig = quorem(b,S) + '0';
  712:                                                 }
  713:                                         if (dig++ == '9')
  714:                                                 goto round_9_up;
  715:                                         inex = STRTOG_Inexhi;
  716:                                         goto accept;
  717:                                         }
  718:                                 if (j1 > 0) {
  719:                                         b = lshift(b, 1);
  720:                                         if (b == NULL)
  721:                                                 return (NULL);
  722:                                         j1 = cmp(b, S);
  723: #ifdef ROUND_BIASED
  724:                                         if (j1 >= 0 /*)*/
  725: #else
  726:                                         if ((j1 > 0 || (j1 == 0 && dig & 1))
  727: #endif
  728:                                         && dig++ == '9')
  729:                                                 goto round_9_up;
  730:                                         inex = STRTOG_Inexhi;
  731:                                         }
  732:                                 if (b->wds > 1 || b->x[0])
  733:                                         inex = STRTOG_Inexlo;
  734:  accept:
  735:                                 *s++ = dig;
  736:                                 goto ret;
  737:                                 }
  738:                         if (j1 > 0 && rdir != 2) {
  739:                                 if (dig == '9') { /* possible if i == 1 */
  740:  round_9_up:
  741:                                         *s++ = '9';
  742:                                         inex = STRTOG_Inexhi;
  743:                                         goto roundoff;
  744:                                         }
  745:                                 inex = STRTOG_Inexhi;
  746:                                 *s++ = dig + 1;
  747:                                 goto ret;
  748:                                 }
  749:                         *s++ = dig;
  750:                         if (i == ilim)
  751:                                 break;
  752:                         b = multadd(b, 10, 0);
  753:                         if (b == NULL)
  754:                                 return (NULL);
  755:                         if (mlo == mhi) {
  756:                                 mlo = mhi = multadd(mhi, 10, 0);
  757:                                 if (mlo == NULL)
  758:                                         return (NULL);
  759:                                 }
  760:                         else {
  761:                                 mlo = multadd(mlo, 10, 0);
  762:                                 if (mlo == NULL)
  763:                                         return (NULL);
  764:                                 mhi = multadd(mhi, 10, 0);
  765:                                 if (mhi == NULL)
  766:                                         return (NULL);
  767:                                 }
  768:                         }
  769:                 }
  770:         else
  771:                 for(i = 1;; i++) {
  772:                         *s++ = dig = quorem(b,S) + '0';
  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:         if (rdir) {
  783:                 if (rdir == 2 || (b->wds <= 1 && !b->x[0]))
  784:                         goto chopzeros;
  785:                 goto roundoff;
  786:                 }
  787:         b = lshift(b, 1);
  788:         if (b == NULL)
  789:                 return (NULL);
  790:         j = cmp(b, S);
  791: #ifdef ROUND_BIASED
  792:         if (j >= 0)
  793: #else
  794:         if (j > 0 || (j == 0 && dig & 1))
  795: #endif
  796:                 {
  797:  roundoff:
  798:                 inex = STRTOG_Inexhi;
  799:                 while(*--s == '9')
  800:                         if (s == s0) {
  801:                                 k++;
  802:                                 *s++ = '1';
  803:                                 goto ret;
  804:                                 }
  805:                 ++*s++;
  806:                 }
  807:         else {
  808:  chopzeros:
  809:                 if (b->wds > 1 || b->x[0])
  810:                         inex = STRTOG_Inexlo;
  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:         Bfree(b);
  823:         *s = 0;
  824:         *decpt = k + 1;
  825:         if (rve)
  826:                 *rve = s;
  827:         *kindp |= inex;
  828:         return s0;
  829:         }