Contiki 2.6

small_dtoa.c

00001 /****************************************************************
00002  *
00003  * The author of this software is David M. Gay.
00004  *
00005  * Copyright (c) 1991 by AT&T.
00006  *
00007  * Permission to use, copy, modify, and distribute this software for any
00008  * purpose without fee is hereby granted, provided that this entire notice
00009  * is included in all copies of any software which is or includes a copy
00010  * or modification of this software and in all copies of the supporting
00011  * documentation for such software.
00012  *
00013  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
00014  * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
00015  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
00016  * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
00017  *
00018  ***************************************************************/
00019 
00020 /* Please send bug reports to
00021         David M. Gay
00022         AT&T Bell Laboratories, Room 2C-463
00023         600 Mountain Avenue
00024         Murray Hill, NJ 07974-2070
00025         U.S.A.
00026         dmg@research.att.com or research!dmg
00027  */
00028  
00029  
00030 #ifndef _SMALL_PRINTF
00031 
00032 #define small_lo0bits   lo0bits
00033 #define small_hi0bits   hi0bits
00034 #define small_i2b                       i2b
00035 #define small_cmp                       cmp
00036 #define small_ulp               ulp
00037 #define small_b2d                       b2d
00038 #define small_d2b                       d2b
00039 #define small_ratio             ratio
00040 
00041 #define small_tens              tens
00042 #define small_bigtens   bigtens
00043 #define small_tinytens  tinytens 
00044 
00045 #endif
00046  
00047  
00048  
00049  
00050 
00051 #include <_ansi.h>
00052 #include <stdlib.h>
00053 
00054 #ifndef _SMALL_PRINTF
00055 #include <reent.h>
00056 #endif
00057 
00058 #include <string.h>
00059 #include "small_mprec.h"
00060 
00061 static int
00062 _DEFUN (quorem,
00063         (b, S),
00064         _Bigint * b _AND _Bigint * S)
00065 {
00066   int n;
00067   __Long borrow, y;
00068   __ULong carry, q, ys;
00069   __ULong *bx, *bxe, *sx, *sxe;
00070 #ifdef Pack_32
00071   __Long z;
00072   __ULong si, zs;
00073 #endif
00074 
00075   n = S->_wds;
00076 #ifdef DEBUG
00077   /*debug*/ if (b->_wds > n)
00078     /*debug*/ Bug ("oversize b in quorem");
00079 #endif
00080   if (b->_wds < n)
00081     return 0;
00082   sx = S->_x;
00083   sxe = sx + --n;
00084   bx = b->_x;
00085   bxe = bx + n;
00086   q = *bxe / (*sxe + 1);        /* ensure q <= true quotient */
00087 #ifdef DEBUG
00088   /*debug*/ if (q > 9)
00089     /*debug*/ Bug ("oversized quotient in quorem");
00090 #endif
00091   if (q)
00092     {
00093       borrow = 0;
00094       carry = 0;
00095       do
00096         {
00097 #ifdef Pack_32
00098           si = *sx++;
00099           ys = (si & 0xffff) * q + carry;
00100           zs = (si >> 16) * q + (ys >> 16);
00101           carry = zs >> 16;
00102           y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
00103           borrow = y >> 16;
00104           Sign_Extend (borrow, y);
00105           z = (*bx >> 16) - (zs & 0xffff) + borrow;
00106           borrow = z >> 16;
00107           Sign_Extend (borrow, z);
00108           Storeinc (bx, z, y);
00109 #else
00110           ys = *sx++ * q + carry;
00111           carry = ys >> 16;
00112           y = *bx - (ys & 0xffff) + borrow;
00113           borrow = y >> 16;
00114           Sign_Extend (borrow, y);
00115           *bx++ = y & 0xffff;
00116 #endif
00117         }
00118       while (sx <= sxe);
00119       if (!*bxe)
00120         {
00121           bx = b->_x;
00122           while (--bxe > bx && !*bxe)
00123             --n;
00124           b->_wds = n;
00125         }
00126     }
00127   
00128   if (small_cmp (b, S) >= 0)
00129     {
00130       q++;
00131       borrow = 0;
00132       carry = 0;
00133       bx = b->_x;
00134       sx = S->_x;
00135       do
00136         {
00137 #ifdef Pack_32
00138           si = *sx++;
00139           ys = (si & 0xffff) + carry;
00140           zs = (si >> 16) + (ys >> 16);
00141           carry = zs >> 16;
00142           y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
00143           borrow = y >> 16;
00144           Sign_Extend (borrow, y);
00145           z = (*bx >> 16) - (zs & 0xffff) + borrow;
00146           borrow = z >> 16;
00147           Sign_Extend (borrow, z);
00148           Storeinc (bx, z, y);
00149 #else
00150           ys = *sx++ + carry;
00151           carry = ys >> 16;
00152           y = *bx - (ys & 0xffff) + borrow;
00153           borrow = y >> 16;
00154           Sign_Extend (borrow, y);
00155           *bx++ = y & 0xffff;
00156 #endif
00157         }
00158       while (sx <= sxe);
00159       bx = b->_x;
00160       bxe = bx + n;
00161       if (!*bxe)
00162         {
00163           while (--bxe > bx && !*bxe)
00164             --n;
00165           b->_wds = n;
00166         }
00167     }
00168   return q;
00169 }
00170 
00171 /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
00172  *
00173  * Inspired by "How to Print Floating-Point Numbers Accurately" by
00174  * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
00175  *
00176  * Modifications:
00177  *      1. Rather than iterating, we use a simple numeric overestimate
00178  *         to determine k = floor(log10(d)).  We scale relevant
00179  *         quantities using O(log2(k)) rather than O(k) multiplications.
00180  *      2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
00181  *         try to generate digits strictly left to right.  Instead, we
00182  *         compute with fewer bits and propagate the carry if necessary
00183  *         when rounding the final digit up.  This is often faster.
00184  *      3. Under the assumption that input will be rounded nearest,
00185  *         mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
00186  *         That is, we allow equality in stopping tests when the
00187  *         round-nearest rule will give the same floating-point value
00188  *         as would satisfaction of the stopping test with strict
00189  *         inequality.
00190  *      4. We remove common factors of powers of 2 from relevant
00191  *         quantities.
00192  *      5. When converting floating-point integers less than 1e16,
00193  *         we use floating-point arithmetic rather than resorting
00194  *         to multiple-precision integers.
00195  *      6. When asked to produce fewer than 15 digits, we first try
00196  *         to get by with floating-point arithmetic; we resort to
00197  *         multiple-precision integer arithmetic only if we cannot
00198  *         guarantee that the floating-point calculation has given
00199  *         the correctly rounded result.  For k requested digits and
00200  *         "uniformly" distributed input, the probability is
00201  *         something like 10^(k-15) that we must resort to the long
00202  *         calculation.
00203  */
00204  
00205  
00206  /* Scanf and printf call both the small_mprec.c file if small_printf 
00207   * has not been specfied optimizations concerning small_mprec.c and
00208   * call of balloc will be performed anyway for printf. 
00209   */
00210  
00211 #ifdef SMALL_SCANF
00212 #ifndef  _SMALL_PRINTF 
00213 #define  _SMALL_PRINTF 
00214 #endif
00215 #endif
00216  
00217 
00218 
00219 char *
00220 _DEFUN (_dtoa_r,
00221         (ptr, _d, mode, ndigits, decpt, sign, rve),
00222         struct _reent *ptr _AND
00223         double _d _AND
00224         int mode _AND
00225         int ndigits _AND
00226         int *decpt _AND
00227         int *sign _AND
00228         char **rve)
00229 {
00230   /*    Arguments ndigits, decpt, sign are similar to those
00231         of ecvt and fcvt; trailing zeros are suppressed from
00232         the returned string.  If not null, *rve is set to point
00233         to the end of the return value.  If d is +-Infinity or NaN,
00234         then *decpt is set to 9999.
00235 
00236         mode:
00237                 0 ==> shortest string that yields d when read in
00238                         and rounded to nearest.
00239                 1 ==> like 0, but with Steele & White stopping rule;
00240                         e.g. with IEEE P754 arithmetic , mode 0 gives
00241                         1e23 whereas mode 1 gives 9.999999999999999e22.
00242                 2 ==> max(1,ndigits) significant digits.  This gives a
00243                         return value similar to that of ecvt, except
00244                         that trailing zeros are suppressed.
00245                 3 ==> through ndigits past the decimal point.  This
00246                         gives a return value similar to that from fcvt,
00247                         except that trailing zeros are suppressed, and
00248                         ndigits can be negative.
00249                 4-9 should give the same return values as 2-3, i.e.,
00250                         4 <= mode <= 9 ==> same return as mode
00251                         2 + (mode & 1).  These modes are mainly for
00252                         debugging; often they run slower but sometimes
00253                         faster than modes 2-3.
00254                 4,5,8,9 ==> left-to-right digit generation.
00255                 6-9 ==> don't try fast floating-point estimate
00256                         (if applicable).
00257 
00258                 Values of mode other than 0-9 are treated as mode 0.
00259 
00260                 Sufficient space is allocated to the return value
00261                 to hold the suppressed trailing zeros.
00262         */
00263 
00264   int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0,
00265     k_check, leftright, m2, m5, s2, s5, spec_case, try_quick;
00266   union double_union d, d2, eps;
00267   __Long L;
00268 #ifndef Sudden_Underflow
00269   int denorm;
00270   __ULong x;
00271 #endif
00272   _Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S;
00273   double ds;
00274   #ifndef _SMALL_PRINTF
00275   char *s, *s0;
00276   
00277   #else //Declarations for SMALL_PRINTF
00278   
00279   /*
00280    *  SIZE have been chosen regarding size allocated by default printf it seems that most of time 32 is sufficient except 
00281    *  for lshift that allocated 40
00282    *  Nevertheless for some examples greater buffer size can be usefull. 
00283    */
00284   
00285   #define BUF_LSHIFT_SIZE 40// Size of each buffer for variables of _Bigint type
00286   #define BUF_SIZE  32
00287   #define S0_SIZE  32 // Size of the buffer result that will be provided by _dtoa_r
00288   
00289   /*  
00290    *    For the SMALL_PRINTF implementation for floating points numbers :  
00291         *  - To avoid the call of allocator we defined a buffer for each variable : instead of taking the adress 
00292         *  provided by Balloc variables are initialized to the beginning of the array.
00293         *       - For some variables many buffers have been declared, in fact for each call of small_lshift we used a 
00294         *  buffer that has not been used at the moment 
00295    *  - This buffers are used in the call of function declared in small_mprec.h 
00296    *  To have more informations look at small_mprec.c 
00297    */
00298   
00299 _Bigint tab_b[BUF_LSHIFT_SIZE],tab_b1[BUF_SIZE],tab_delta[BUF_SIZE],tab_mlo[BUF_SIZE],tab_mhi[BUF_LSHIFT_SIZE],tab_S[BUF_LSHIFT_SIZE];
00300 _Bigint tab_blshift[BUF_LSHIFT_SIZE],tab_Slshift[BUF_LSHIFT_SIZE],tab_mhilshift[BUF_LSHIFT_SIZE],tab_mlolshift[BUF_LSHIFT_SIZE];
00301   char tab_s0[S0_SIZE];
00302   char *s, *s0;
00303   #endif  //Declarations for SMALL_PRINTF
00304 
00305    d.d = _d;
00306 #ifndef _SMALL_PRINTF
00307   _REENT_CHECK_MP(ptr);
00308   if (_REENT_MP_RESULT(ptr))
00309     {
00310       _REENT_MP_RESULT(ptr)->_k = _REENT_MP_RESULT_K(ptr);
00311       _REENT_MP_RESULT(ptr)->_maxwds = 1 << _REENT_MP_RESULT_K(ptr);     
00312       Bfree (ptr, _REENT_MP_RESULT(ptr));
00313       _REENT_MP_RESULT(ptr) = 0;
00314     }
00315  #endif
00316   if (word0 (d) & Sign_bit)
00317     {
00318       /* set sign for everything, including 0's and NaNs */
00319       *sign = 1;
00320       word0 (d) &= ~Sign_bit;   /* clear sign bit */
00321     }
00322   else
00323     *sign = 0;
00324 
00325 #if defined(IEEE_Arith) + defined(VAX)
00326 #ifdef IEEE_Arith
00327   if ((word0 (d) & Exp_mask) == Exp_mask)
00328 #else
00329   if (word0 (d) == 0x8000)
00330 #endif
00331     {
00332       /* Infinity or NaN */
00333       *decpt = 9999;
00334       s =
00335 #ifdef IEEE_Arith
00336         !word1 (d) && !(word0 (d) & 0xfffff) ? "Infinity" :
00337 #endif
00338         "NaN";
00339       if (rve)
00340         *rve =
00341 #ifdef IEEE_Arith
00342           s[3] ? s + 8 :
00343 #endif
00344           s + 3;
00345 
00346 
00347       return s;
00348     }
00349 
00350 #ifdef IBM
00351   d.d += 0;                     /* normalize */
00352 #endif
00353   if (!d.d)
00354     {
00355       *decpt = 1;
00356       s = "0";
00357       if (rve)
00358          *rve = s + 1;
00359           
00360       return s;
00361     }
00362    #ifdef _SMALL_PRINTF
00363    b = small_d2b (ptr, d.d, &be, &bbits,&tab_b[0]);
00364    #else
00365    b = small_d2b (ptr, d.d, &be, &bbits);
00366    #endif
00367   
00368 #ifdef Sudden_Underflow
00369   i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1));
00370 #else
00371   if ((i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1))) != 0)
00372     {
00373 #endif
00374       d2.d = d.d;
00375       word0 (d2) &= Frac_mask1;
00376       word0 (d2) |= Exp_11;
00377 #ifdef IBM
00378       if (j = 11 - hi0bits (word0 (d2) & Frac_mask))
00379         d2.d /= 1 << j;
00380 #endif
00381 
00382       /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
00383                  * log10(x)      =  log(x) / log(10)
00384                  *              ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
00385                  * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
00386                  *
00387                  * This suggests computing an approximation k to log10(d) by
00388                  *
00389                  * k = (i - Bias)*0.301029995663981
00390                  *      + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
00391                  *
00392                  * We want k to be too large rather than too small.
00393                  * The error in the first-order Taylor series approximation
00394                  * is in our favor, so we just round up the constant enough
00395                  * to compensate for any error in the multiplication of
00396                  * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
00397                  * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
00398                  * adding 1e-13 to the constant term more than suffices.
00399                  * Hence we adjust the constant term to 0.1760912590558.
00400                  * (We could get a more accurate k by invoking log10,
00401                  *  but this is probably not worthwhile.)
00402                  */
00403 
00404       i -= Bias;
00405 #ifdef IBM
00406       i <<= 2;
00407       i += j;
00408 #endif
00409 #ifndef Sudden_Underflow
00410       denorm = 0;
00411     }
00412   else
00413     {
00414       /* d is denormalized */
00415 
00416       i = bbits + be + (Bias + (P - 1) - 1);
00417       x = (i > 32) ? (word0 (d) << (64 - i)) | (word1 (d) >> (i - 32))
00418        : (word1 (d) << (32 - i));
00419       d2.d = x;
00420       word0 (d2) -= 31 * Exp_msk1;      /* adjust exponent */
00421       i -= (Bias + (P - 1) - 1) + 1;
00422       denorm = 1;
00423     }
00424 #endif
00425   ds = (d2.d - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981;
00426   k = (int) ds;
00427   if (ds < 0. && ds != k)
00428     k--;                        /* want k = floor(ds) */
00429   k_check = 1;
00430   if (k >= 0 && k <= Ten_pmax)
00431     {
00432       if (d.d < small_tens[k])
00433         k--;
00434       k_check = 0;
00435     }
00436   j = bbits - i - 1;
00437   if (j >= 0)
00438     {
00439       b2 = 0;
00440       s2 = j;
00441     }
00442   else
00443     {
00444       b2 = -j;
00445       s2 = 0;
00446     }
00447   if (k >= 0)
00448     {
00449       b5 = 0;
00450       s5 = k;
00451       s2 += k;
00452     }
00453   else
00454     {
00455       b2 -= k;
00456       b5 = -k;
00457       s5 = 0;
00458     }
00459   if (mode < 0 || mode > 9)
00460     mode = 0;
00461   try_quick = 1;
00462   if (mode > 5)
00463     {
00464       mode -= 4;
00465       try_quick = 0;
00466     }
00467   leftright = 1;
00468   ilim = ilim1 = -1;
00469   switch (mode)
00470     {
00471     case 0:
00472     case 1:
00473       i = 18;
00474       ndigits = 0;
00475       break;
00476     case 2:
00477       leftright = 0;
00478       /* no break */
00479     case 4:
00480       if (ndigits <= 0)
00481         ndigits = 1;
00482       ilim = ilim1 = i = ndigits;
00483       break;
00484     case 3:
00485       leftright = 0;
00486       /* no break */
00487     case 5:
00488       i = ndigits + k + 1;
00489       ilim = i;
00490       ilim1 = i - 1;
00491       if (i <= 0)
00492         i = 1;
00493     }
00494   j = sizeof (__ULong);
00495   #ifndef _SMALL_PRINTF
00496   for (_REENT_MP_RESULT_K(ptr) = 0; sizeof (_Bigint) - sizeof (__ULong) + j <= i;
00497        j <<= 1)
00498   _REENT_MP_RESULT_K(ptr)++;  
00499   _REENT_MP_RESULT(ptr) = Balloc (ptr, _REENT_MP_RESULT_K(ptr));
00500   s = s0 = (char *) _REENT_MP_RESULT(ptr);
00501   #else
00502   s = s0 = &tab_s0[0];
00503   #endif
00504   
00505   if (ilim >= 0 && ilim <= Quick_max && try_quick)
00506     {
00507       /* Try to get by with floating-point arithmetic. */
00508 
00509       i = 0;
00510       d2.d = d.d;
00511       k0 = k;
00512       ilim0 = ilim;
00513       ieps = 2;                 /* conservative */
00514       if (k > 0)
00515         {
00516           ds = small_tens[k & 0xf];
00517           j = k >> 4;
00518           if (j & Bletch)
00519             {
00520               /* prevent overflows */
00521               j &= Bletch - 1;
00522               d.d /= small_bigtens[n_bigtens - 1];
00523               ieps++;
00524             }
00525           for (; j; j >>= 1, i++)
00526             if (j & 1)
00527               {
00528                 ieps++;
00529                 ds *= small_bigtens[i];
00530               }
00531           d.d /= ds;
00532         }
00533       else if ((j1 = -k) != 0)
00534         {
00535           d.d *= small_tens[j1 & 0xf];
00536           for (j = j1 >> 4; j; j >>= 1, i++)
00537             if (j & 1)
00538               {
00539                 ieps++;
00540                 d.d *= small_bigtens[i];
00541               }
00542         }
00543       if (k_check && d.d < 1. && ilim > 0)
00544         {
00545           if (ilim1 <= 0)
00546             goto fast_failed;
00547           ilim = ilim1;
00548           k--;
00549           d.d *= 10.;
00550           ieps++;
00551         }
00552       eps.d = ieps * d.d + 7.;
00553       word0 (eps) -= (P - 1) * Exp_msk1;
00554       if (ilim == 0)
00555         {
00556           S = mhi = 0;
00557           d.d -= 5.;
00558           if (d.d > eps.d)
00559             goto one_digit;
00560           if (d.d < -eps.d)
00561             goto no_digits;
00562           goto fast_failed;
00563         }
00564 #ifndef No_leftright
00565       if (leftright)
00566         {
00567           /* Use Steele & White method of only
00568            * generating digits needed.
00569            */
00570           eps.d = 0.5 / small_tens[ilim - 1] - eps.d;
00571           for (i = 0;;)
00572             {
00573               L = d.d;
00574               d.d -= L;
00575               
00576               *s++ = '0' + (int) L;
00577               
00578               if (d.d < eps.d)
00579                 goto ret1;
00580               if (1. - d.d < eps.d)
00581                 goto bump_up;
00582               if (++i >= ilim)
00583                 break;
00584               eps.d *= 10.;
00585               d.d *= 10.;
00586             }
00587         }
00588       else
00589         {
00590 #endif
00591           /* Generate ilim digits, then fix them up. */
00592           eps.d *= small_tens[ilim - 1];
00593           for (i = 1;; i++, d.d *= 10.)
00594             {
00595               L = d.d;
00596               d.d -= L;       
00597               *s++ = '0' + (int) L;           
00598               if (i == ilim)
00599                 {
00600                   if (d.d > 0.5 + eps.d)
00601                     goto bump_up;
00602                   else if (d.d < 0.5 - eps.d)
00603                     {                 
00604                       while (*--s == '0');
00605                       s++;                  
00606                       goto ret1;
00607                     }
00608                   break;
00609                 }
00610             }
00611 #ifndef No_leftright
00612         }
00613 #endif
00614     fast_failed:
00615       s = s0;
00616       d.d = d2.d;
00617       k = k0;
00618       ilim = ilim0;
00619     }
00620 
00621   /* Do we have a "small" integer? */
00622 
00623   if (be >= 0 && k <= Int_max)
00624     {
00625       /* Yes. */
00626       ds = small_tens[k];
00627       if (ndigits < 0 && ilim <= 0)
00628         {
00629           S = mhi = 0;
00630           if (ilim < 0 || d.d <= 5 * ds)
00631             goto no_digits;
00632           goto one_digit;
00633         }
00634       for (i = 1;; i++)
00635         {
00636           L = d.d / ds;
00637           d.d -= L * ds;
00638 #ifdef Check_FLT_ROUNDS
00639           /* If FLT_ROUNDS == 2, L will usually be high by 1 */
00640           if (d.d < 0)
00641             {
00642               L--;
00643               d.d += ds;
00644             }
00645 #endif
00646          
00647               *s++ = '0' + (int) L;
00648         
00649           if (i == ilim)
00650             {
00651               d.d += d.d;
00652              if ((d.d > ds) || ((d.d == ds) && (L & 1)))
00653                 {
00654                 bump_up:
00655                  
00656                  
00657                  
00658                   while (*--s == '9')
00659                     if (s == s0)
00660                       {
00661                         k++;
00662                         *s = '0';
00663                         break;
00664                       }
00665                   ++*s++;
00666         
00667                 }
00668               break;
00669             }
00670           if (!(d.d *= 10.))
00671             break;
00672         }
00673       goto ret1;
00674     }
00675 
00676   m2 = b2;
00677   m5 = b5;
00678   mhi = mlo = 0;
00679   if (leftright)
00680     {
00681       if (mode < 2)
00682         {
00683           i =
00684 #ifndef Sudden_Underflow
00685             denorm ? be + (Bias + (P - 1) - 1 + 1) :
00686 #endif
00687 #ifdef IBM
00688             1 + 4 * P - 3 - bbits + ((bbits + be - 1) & 3);
00689 #else
00690             1 + P - bbits;
00691 #endif
00692         }
00693       else
00694         {
00695           j = ilim - 1;
00696           if (m5 >= j)
00697             m5 -= j;
00698           else
00699             {
00700               s5 += j -= m5;
00701               b5 += j;
00702               m5 = 0;
00703             }
00704           if ((i = ilim) < 0)
00705             {
00706               m2 -= i;
00707               i = 0;
00708             }
00709         }
00710       b2 += i;
00711       s2 += i;
00712                 
00713            #ifdef _SMALL_PRINTF 
00714       mhi = small_i2b (ptr, 1,&tab_mhi[0]);
00715       #else
00716       mhi=i2b(ptr,1);
00717       #endif
00718     }
00719   if (m2 > 0 && s2 > 0)
00720     {
00721       i = m2 < s2 ? m2 : s2;
00722       b2 -= i;
00723       m2 -= i;
00724       s2 -= i;
00725     }
00726   if (b5 > 0)
00727     {
00728       if (leftright)
00729         {
00730           if (m5 > 0)
00731             {
00732               #ifdef _SMALL_PRINTF
00733               if (mhi == &tab_mhi[0]){
00734               mhi = small_pow5mult (ptr, mhi, m5,&tab_mhilshift[0]);
00735               }
00736               else{
00737               mhi = small_pow5mult (ptr, mhi, m5,&tab_mhi[0]);
00738               }
00739               
00740               b1 = small_mult (ptr, mhi, b,&tab_b1[0]);
00741               #else 
00742                 mhi = pow5mult (ptr, mhi, m5);
00743                         b1 = mult (ptr, mhi, b);              
00744                 Bfree (ptr, b);
00745               #endif
00746             }
00747          if ((j = b5 - m5) != 0)
00748        #ifdef _SMALL_PRINTF
00749             if( b == &tab_b[0]){
00750            b = small_pow5mult (ptr, b, b5,&tab_blshift[0]);
00751            }
00752        else{
00753            b = small_pow5mult (ptr, b, b5,&tab_b[0]);
00754            }
00755             #else
00756             b = pow5mult (ptr, b, j);
00757             #endif
00758             
00759          
00760 
00761         }
00762       else
00763         #ifdef _SMALL_PRINTF  
00764            if( b == &tab_b[0]){
00765            b = small_pow5mult (ptr, b, b5,&tab_blshift[0]);
00766            }
00767            else{
00768            b = small_pow5mult (ptr, b, b5,&tab_b[0]);
00769            }
00770                      
00771         #else
00772                 b = pow5mult (ptr, b, b5);
00773              #endif
00774 
00775     }
00776   #ifdef _SMALL_PRINTF  
00777   S = small_i2b (ptr, 1,&tab_S[0]);
00778   #else
00779   S = small_i2b (ptr, 1);
00780   #endif
00781   if (s5 > 0)
00782     #ifdef _SMALL_PRINTF
00783     if (S == &tab_S[0]){
00784     S = small_pow5mult (ptr, S, s5,&tab_Slshift[0]);
00785     }
00786     else{
00787     S = small_pow5mult (ptr, S, s5,&tab_S[0]);
00788     }
00789     
00790     #else
00791     S = pow5mult (ptr, S, s5);
00792     #endif
00793 
00794   /* Check for special case that d is a normalized power of 2. */
00795 
00796   spec_case = 0;
00797   if (mode < 2)
00798     {
00799       if (!word1 (d) && !(word0 (d) & Bndry_mask)
00800 #ifndef Sudden_Underflow
00801           && word0 (d) & Exp_mask
00802 #endif
00803         )
00804         {
00805           /* The special case */
00806           b2 += Log2P;
00807           s2 += Log2P;
00808           spec_case = 1;
00809         }
00810     }
00811 
00812   /* Arrange for convenient computation of quotients:
00813    * shift left if necessary so divisor has 4 leading 0 bits.
00814    *
00815    * Perhaps we should just compute leading 28 bits of S once
00816    * and for all and pass them and a shift to quorem, so it
00817    * can do shifts and ors to compute the numerator for q.
00818    */
00819 
00820 #ifdef Pack_32
00821   if ((i = ((s5 ? 32 -small_hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0x1f) != 0)
00822     i = 32 - i;
00823 #else
00824   if ((i = ((s5 ? 32 - small_hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0xf) != 0)
00825     i = 16 - i;
00826 #endif
00827   if (i > 4)
00828     {
00829       i -= 4;
00830       b2 += i;
00831       m2 += i;
00832       s2 += i;
00833     }
00834   else if (i < 4)
00835     {
00836       i += 28;
00837       b2 += i;
00838       m2 += i;
00839       s2 += i;
00840     }
00841   if (b2 > 0)
00842     #ifdef _SMALL_PRINTF
00843       if (b==&tab_b[0]){
00844                 b = small_lshift (ptr, b, b2,&tab_blshift[0]);
00845         }
00846         else {
00847            b = small_lshift (ptr, b, b2,&tab_b[0]);
00848         }
00849      #else
00850          b = lshift (ptr, b, b2);
00851      #endif
00852   if (s2 > 0)
00853     #ifdef _SMALL_PRINTF 
00854       if ( S == tab_S) { 
00855         S = small_lshift (ptr, S, s2,&tab_Slshift[0]);  
00856         }
00857         else {
00858         S = small_lshift (ptr, S, s2,&tab_S[0]); 
00859         }
00860     #else
00861       S = lshift (ptr, S, s2);
00862     #endif
00863   if (k_check)
00864     {
00865       if (small_cmp (b, S) < 0)
00866         {
00867           k--;    /* we botched the k estimate */
00868           #ifdef _SMALL_PRINTF     
00869             if (b == &tab_b[0] ){
00870             
00871             b = small_multadd (ptr, b, 10, 0,&tab_blshift[0]);  
00872             }
00873             else{
00874             b = small_multadd (ptr, b, 10, 0,&tab_b[0]);        
00875             }
00876           #else
00877             b = multadd (ptr, b, 10, 0);                  
00878           #endif
00879 
00880         
00881           if (leftright)
00882             #ifdef _SMALL_PRINTF
00883             if (mhi == &tab_mhi[0] ){
00884             
00885             mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhilshift[0]);    
00886             }
00887             else{
00888             mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhi[0]);  
00889             }       
00890             #else
00891                mhi = multadd (ptr, mhi, 10, 0);
00892             #endif
00893           ilim = ilim1;
00894         }
00895     }
00896   if (ilim <= 0 && mode > 2)
00897     {
00898       #ifdef _SMALL_PRINTF
00899       _Bigint * tab;
00900       if ( S == &tab_S[0] ){
00901       tab = tab_Slshift;
00902       }
00903       else {
00904       tab = tab_S;
00905       }
00906       
00907       if (ilim < 0 || small_cmp (b, S = small_multadd (ptr, S, 5, 0,&tab[0])) <= 0)
00908         {
00909            #else
00910            if (ilim < 0 || small_cmp (b, S = multadd (ptr, S, 5, 0)) <= 0)
00911         {
00912            #endif
00913           /* no digits, fcvt style */
00914         no_digits:
00915           k = -1 - ndigits;
00916           goto ret;
00917         }
00918     one_digit: 
00919       *s++ = '1'; 
00920       k++;
00921       goto ret;
00922     }
00923   if (leftright)
00924     {
00925       if (m2 > 0)
00926    #ifdef _SMALL_PRINTF   
00927    if (mhi == &tab_mhi[0]){
00928      mhi = small_lshift (ptr, mhi, m2,&tab_mhilshift[0]);
00929     }
00930    else {
00931      mhi = small_lshift (ptr, mhi, m2,&tab_mhi[0]);
00932    }
00933    
00934    #else
00935      mhi = lshift (ptr, mhi, m2);
00936    #endif
00937       /* Compute mlo -- check for special case
00938        * that d is a normalized power of 2.
00939        */
00940 
00941       mlo = mhi;
00942       if (spec_case)
00943         {
00944           #ifndef _SMALL_PRINTF
00945           
00946           mhi = Balloc (ptr, mhi->_k);
00947           
00948           #else
00949           int sauv_k =mhi->_k;
00950           mhi =&tab_mhi[0];
00951           mhi->_k = sauv_k;
00952           mhi->_maxwds = (1<<sauv_k);
00953           mhi->_sign = mhi->_wds =0 ;     
00954           #endif
00955           Bcopy (mhi, mlo); 
00956           
00957           #ifdef _SMALL_PRINTF
00958           if( mhi == &tab_mhi[0]){
00959                  mhi = small_lshift (ptr, mhi, Log2P,&tab_mhilshift[0]);
00960           }     
00961           else {
00962            mhi = small_lshift (ptr, mhi, Log2P,&tab_mhi[0]);
00963            }
00964           #else
00965             mhi = lshift (ptr, mhi, Log2P);
00966           #endif
00967         }
00968 
00969       for (i = 1;; i++)
00970         {
00971           dig = quorem (b, S) + '0';
00972           /* Do we yet have the shortest decimal string
00973            * that will round to d?
00974            */
00975           j = small_cmp (b, mlo);
00976           #ifdef _SMALL_PRINTF
00977           delta = small_diff (ptr, S, mhi,&tab_delta[0]);
00978           #else
00979           delta = diff (ptr, S, mhi);
00980           #endif
00981           j1 = delta->_sign ? 1 : small_cmp (b, delta);
00982           #ifndef _SMALL_PRINTF
00983           Bfree (ptr, delta);
00984           #endif
00985 #ifndef ROUND_BIASED
00986           if (j1 == 0 && !mode && !(word1 (d) & 1))
00987             {
00988               if (dig == '9')
00989                 goto round_9_up;
00990               if (j > 0)
00991                 dig++;
00992                    
00993               *s++ = dig;
00994              
00995               goto ret;
00996             }
00997 #endif
00998          if ((j < 0) || ((j == 0) && !mode
00999 #ifndef ROUND_BIASED
01000               && !(word1 (d) & 1)
01001 #endif
01002            ))
01003             {
01004               if (j1 > 0)
01005                 {
01006                   
01007                   #ifdef _SMALL_PRINTF
01008                   if (b == &tab_b[0]){
01009                                 b = small_lshift (ptr, b, 1,&tab_blshift[0]);           
01010                   }
01011                   else {
01012                         b = small_lshift (ptr, b, 1,&tab_b[0]);         
01013                   }
01014                   #else
01015                   b = lshift (ptr, b, 1);
01016                   #endif
01017 
01018                   j1 = small_cmp (b, S);
01019                  if (((j1 > 0) || ((j1 == 0) && (dig & 1)))
01020                       && dig++ == '9')
01021                     goto round_9_up;
01022                 }
01023               
01024               *s++ = dig;
01025               
01026               goto ret;
01027             }
01028           if (j1 > 0)
01029             {
01030               if (dig == '9')
01031                 {               /* possible if i == 1 */
01032                 round_9_up:
01033                  
01034               *s++ = '9';
01035              
01036                   goto roundoff;
01037                 }
01038               
01039               *s++ = dig+1;
01040               
01041               goto ret;
01042             }
01043          
01044               *s++ = dig;
01045               
01046           if (i == ilim)
01047             break;
01048           #ifdef _SMALL_PRINTF  
01049              if (b == tab_b ){
01050               b = small_multadd (ptr, b, 10, 0,&tab_blshift[0]);
01051              }
01052              else{
01053               b = small_multadd (ptr, b, 10, 0,&tab_b[0]);
01054              }   
01055         
01056           #else
01057              b = multadd (ptr, b, 10, 0);
01058           #endif
01059           
01060           
01061           if (mlo == mhi)
01062             #ifdef _SMALL_PRINTF        
01063              if ( mhi = &tab_mhi[0] ) {   
01064                         mlo = mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhilshift[0]);
01065              }
01066              else{
01067                 mlo = mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhi[0]);
01068              }
01069              
01070             #else
01071             mlo = mhi = multadd (ptr, mhi, 10, 0);
01072             #endif
01073           else
01074             {
01075              
01076              #ifdef _SMALL_PRINTF         
01077               if ( mlo = &tab_mhi[0] ) {   
01078                         mlo  = small_multadd (ptr, mlo, 10, 0,&tab_mlolshift[0]);
01079              }
01080              else{
01081                 mlo = small_multadd (ptr, mlo, 10, 0,&tab_mlo[0]);
01082              }
01083                 if ( mhi = &tab_mhi[0] ) {   
01084                         mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhilshift[0]);
01085              }
01086              else{
01087                 mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhi[0]);
01088              }
01089              #else
01090               mlo = multadd (ptr, mlo, 10, 0);
01091               mhi = multadd (ptr, mhi, 10, 0);
01092              #endif
01093             }
01094         }
01095     }
01096   else
01097     for (i = 1;; i++)
01098       {
01099       
01100              *s++ = dig =quorem (b, S) + '0';
01101               
01102         
01103         if (i >= ilim)
01104           break;
01105    #ifdef _SMALL_PRINTF  
01106     if ( b == &tab_b[0] ) {   
01107           b = small_multadd (ptr, b, 10, 0,&tab_blshift[0]);     
01108           }
01109         else {
01110          b = small_multadd (ptr, b, 10, 0,&tab_b[0]);    
01111         } 
01112         #else
01113           b = multadd (ptr, b, 10, 0);
01114         #endif
01115       }
01116 
01117   /* Round off last digit */
01118   #ifdef _SMALL_PRINTF
01119    if (b == &tab_b[0]) {
01120                 b = small_lshift (ptr, b, 1,&tab_blshift[0]);
01121         }
01122         else {
01123           b = small_lshift (ptr, b, 1,&tab_b[0]);
01124         }
01125   #else
01126       b = lshift (ptr, b, 1);
01127   #endif
01128   
01129   j = small_cmp (b, S);
01130   if ((j > 0) || ((j == 0) && (dig & 1)))
01131     {
01132     roundoff:
01133      
01134    
01135       while (*--s == '9')
01136         if (s == s0)
01137           {
01138             k++;
01139             *s++ = '1';
01140             goto ret;
01141           }
01142       ++*s++;
01143     }
01144   else
01145     {
01146       while (*--s == '0');
01147       s++;
01148     }
01149   
01150     
01151   
01152 ret:
01153   #ifndef _SMALL_PRINTF
01154   Bfree (ptr, S);
01155   
01156   if (mhi)
01157     {
01158       if (mlo && mlo != mhi)
01159         Bfree (ptr, mlo);
01160       Bfree (ptr, mhi);
01161     }
01162   #endif
01163 ret1:
01164   #ifndef _SMALL_PRINTF
01165   Bfree (ptr, b); 
01166   #endif  
01167   *s = 0;
01168   #endif
01169   *decpt = k + 1;
01170   if (rve)
01171     *rve = s;
01172   return s0;
01173 }
01174