Contiki 2.5
small_dtoa.c
1 /****************************************************************
2  *
3  * The author of this software is David M. Gay.
4  *
5  * Copyright (c) 1991 by AT&T.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose without fee is hereby granted, provided that this entire notice
9  * is included in all copies of any software which is or includes a copy
10  * or modification of this software and in all copies of the supporting
11  * documentation for such software.
12  *
13  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
14  * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
15  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
16  * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
17  *
18  ***************************************************************/
19 
20 /* Please send bug reports to
21  David M. Gay
22  AT&T Bell Laboratories, Room 2C-463
23  600 Mountain Avenue
24  Murray Hill, NJ 07974-2070
25  U.S.A.
26  dmg@research.att.com or research!dmg
27  */
28 
29 
30 #ifndef _SMALL_PRINTF
31 
32 #define small_lo0bits lo0bits
33 #define small_hi0bits hi0bits
34 #define small_i2b i2b
35 #define small_cmp cmp
36 #define small_ulp ulp
37 #define small_b2d b2d
38 #define small_d2b d2b
39 #define small_ratio ratio
40 
41 #define small_tens tens
42 #define small_bigtens bigtens
43 #define small_tinytens tinytens
44 
45 #endif
46 
47 
48 
49 
50 
51 #include <_ansi.h>
52 #include <stdlib.h>
53 
54 #ifndef _SMALL_PRINTF
55 #include <reent.h>
56 #endif
57 
58 #include <string.h>
59 #include "small_mprec.h"
60 
61 static int
62 _DEFUN (quorem,
63  (b, S),
64  _Bigint * b _AND _Bigint * S)
65 {
66  int n;
67  __Long borrow, y;
68  __ULong carry, q, ys;
69  __ULong *bx, *bxe, *sx, *sxe;
70 #ifdef Pack_32
71  __Long z;
72  __ULong si, zs;
73 #endif
74 
75  n = S->_wds;
76 #ifdef DEBUG
77  /*debug*/ if (b->_wds > n)
78  /*debug*/ Bug ("oversize b in quorem");
79 #endif
80  if (b->_wds < n)
81  return 0;
82  sx = S->_x;
83  sxe = sx + --n;
84  bx = b->_x;
85  bxe = bx + n;
86  q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
87 #ifdef DEBUG
88  /*debug*/ if (q > 9)
89  /*debug*/ Bug ("oversized quotient in quorem");
90 #endif
91  if (q)
92  {
93  borrow = 0;
94  carry = 0;
95  do
96  {
97 #ifdef Pack_32
98  si = *sx++;
99  ys = (si & 0xffff) * q + carry;
100  zs = (si >> 16) * q + (ys >> 16);
101  carry = zs >> 16;
102  y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
103  borrow = y >> 16;
104  Sign_Extend (borrow, y);
105  z = (*bx >> 16) - (zs & 0xffff) + borrow;
106  borrow = z >> 16;
107  Sign_Extend (borrow, z);
108  Storeinc (bx, z, y);
109 #else
110  ys = *sx++ * q + carry;
111  carry = ys >> 16;
112  y = *bx - (ys & 0xffff) + borrow;
113  borrow = y >> 16;
114  Sign_Extend (borrow, y);
115  *bx++ = y & 0xffff;
116 #endif
117  }
118  while (sx <= sxe);
119  if (!*bxe)
120  {
121  bx = b->_x;
122  while (--bxe > bx && !*bxe)
123  --n;
124  b->_wds = n;
125  }
126  }
127 
128  if (small_cmp (b, S) >= 0)
129  {
130  q++;
131  borrow = 0;
132  carry = 0;
133  bx = b->_x;
134  sx = S->_x;
135  do
136  {
137 #ifdef Pack_32
138  si = *sx++;
139  ys = (si & 0xffff) + carry;
140  zs = (si >> 16) + (ys >> 16);
141  carry = zs >> 16;
142  y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
143  borrow = y >> 16;
144  Sign_Extend (borrow, y);
145  z = (*bx >> 16) - (zs & 0xffff) + borrow;
146  borrow = z >> 16;
147  Sign_Extend (borrow, z);
148  Storeinc (bx, z, y);
149 #else
150  ys = *sx++ + carry;
151  carry = ys >> 16;
152  y = *bx - (ys & 0xffff) + borrow;
153  borrow = y >> 16;
154  Sign_Extend (borrow, y);
155  *bx++ = y & 0xffff;
156 #endif
157  }
158  while (sx <= sxe);
159  bx = b->_x;
160  bxe = bx + n;
161  if (!*bxe)
162  {
163  while (--bxe > bx && !*bxe)
164  --n;
165  b->_wds = n;
166  }
167  }
168  return q;
169 }
170 
171 /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
172  *
173  * Inspired by "How to Print Floating-Point Numbers Accurately" by
174  * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
175  *
176  * Modifications:
177  * 1. Rather than iterating, we use a simple numeric overestimate
178  * to determine k = floor(log10(d)). We scale relevant
179  * quantities using O(log2(k)) rather than O(k) multiplications.
180  * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
181  * try to generate digits strictly left to right. Instead, we
182  * compute with fewer bits and propagate the carry if necessary
183  * when rounding the final digit up. This is often faster.
184  * 3. Under the assumption that input will be rounded nearest,
185  * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
186  * That is, we allow equality in stopping tests when the
187  * round-nearest rule will give the same floating-point value
188  * as would satisfaction of the stopping test with strict
189  * inequality.
190  * 4. We remove common factors of powers of 2 from relevant
191  * quantities.
192  * 5. When converting floating-point integers less than 1e16,
193  * we use floating-point arithmetic rather than resorting
194  * to multiple-precision integers.
195  * 6. When asked to produce fewer than 15 digits, we first try
196  * to get by with floating-point arithmetic; we resort to
197  * multiple-precision integer arithmetic only if we cannot
198  * guarantee that the floating-point calculation has given
199  * the correctly rounded result. For k requested digits and
200  * "uniformly" distributed input, the probability is
201  * something like 10^(k-15) that we must resort to the long
202  * calculation.
203  */
204 
205 
206  /* Scanf and printf call both the small_mprec.c file if small_printf
207  * has not been specfied optimizations concerning small_mprec.c and
208  * call of balloc will be performed anyway for printf.
209  */
210 
211 #ifdef SMALL_SCANF
212 #ifndef _SMALL_PRINTF
213 #define _SMALL_PRINTF
214 #endif
215 #endif
216 
217 
218 
219 char *
220 _DEFUN (_dtoa_r,
221  (ptr, _d, mode, ndigits, decpt, sign, rve),
222  struct _reent *ptr _AND
223  double _d _AND
224  int mode _AND
225  int ndigits _AND
226  int *decpt _AND
227  int *sign _AND
228  char **rve)
229 {
230  /* Arguments ndigits, decpt, sign are similar to those
231  of ecvt and fcvt; trailing zeros are suppressed from
232  the returned string. If not null, *rve is set to point
233  to the end of the return value. If d is +-Infinity or NaN,
234  then *decpt is set to 9999.
235 
236  mode:
237  0 ==> shortest string that yields d when read in
238  and rounded to nearest.
239  1 ==> like 0, but with Steele & White stopping rule;
240  e.g. with IEEE P754 arithmetic , mode 0 gives
241  1e23 whereas mode 1 gives 9.999999999999999e22.
242  2 ==> max(1,ndigits) significant digits. This gives a
243  return value similar to that of ecvt, except
244  that trailing zeros are suppressed.
245  3 ==> through ndigits past the decimal point. This
246  gives a return value similar to that from fcvt,
247  except that trailing zeros are suppressed, and
248  ndigits can be negative.
249  4-9 should give the same return values as 2-3, i.e.,
250  4 <= mode <= 9 ==> same return as mode
251  2 + (mode & 1). These modes are mainly for
252  debugging; often they run slower but sometimes
253  faster than modes 2-3.
254  4,5,8,9 ==> left-to-right digit generation.
255  6-9 ==> don't try fast floating-point estimate
256  (if applicable).
257 
258  Values of mode other than 0-9 are treated as mode 0.
259 
260  Sufficient space is allocated to the return value
261  to hold the suppressed trailing zeros.
262  */
263 
264  int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0,
265  k_check, leftright, m2, m5, s2, s5, spec_case, try_quick;
266  union double_union d, d2, eps;
267  __Long L;
268 #ifndef Sudden_Underflow
269  int denorm;
270  __ULong x;
271 #endif
272  _Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S;
273  double ds;
274  #ifndef _SMALL_PRINTF
275  char *s, *s0;
276 
277  #else //Declarations for SMALL_PRINTF
278 
279  /*
280  * SIZE have been chosen regarding size allocated by default printf it seems that most of time 32 is sufficient except
281  * for lshift that allocated 40
282  * Nevertheless for some examples greater buffer size can be usefull.
283  */
284 
285  #define BUF_LSHIFT_SIZE 40// Size of each buffer for variables of _Bigint type
286  #define BUF_SIZE 32
287  #define S0_SIZE 32 // Size of the buffer result that will be provided by _dtoa_r
288 
289  /*
290  * For the SMALL_PRINTF implementation for floating points numbers :
291  * - To avoid the call of allocator we defined a buffer for each variable : instead of taking the adress
292  * provided by Balloc variables are initialized to the beginning of the array.
293  * - For some variables many buffers have been declared, in fact for each call of small_lshift we used a
294  * buffer that has not been used at the moment
295  * - This buffers are used in the call of function declared in small_mprec.h
296  * To have more informations look at small_mprec.c
297  */
298 
299 _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];
300 _Bigint tab_blshift[BUF_LSHIFT_SIZE],tab_Slshift[BUF_LSHIFT_SIZE],tab_mhilshift[BUF_LSHIFT_SIZE],tab_mlolshift[BUF_LSHIFT_SIZE];
301  char tab_s0[S0_SIZE];
302  char *s, *s0;
303  #endif //Declarations for SMALL_PRINTF
304 
305  d.d = _d;
306 #ifndef _SMALL_PRINTF
307  _REENT_CHECK_MP(ptr);
308  if (_REENT_MP_RESULT(ptr))
309  {
310  _REENT_MP_RESULT(ptr)->_k = _REENT_MP_RESULT_K(ptr);
311  _REENT_MP_RESULT(ptr)->_maxwds = 1 << _REENT_MP_RESULT_K(ptr);
312  Bfree (ptr, _REENT_MP_RESULT(ptr));
313  _REENT_MP_RESULT(ptr) = 0;
314  }
315  #endif
316  if (word0 (d) & Sign_bit)
317  {
318  /* set sign for everything, including 0's and NaNs */
319  *sign = 1;
320  word0 (d) &= ~Sign_bit; /* clear sign bit */
321  }
322  else
323  *sign = 0;
324 
325 #if defined(IEEE_Arith) + defined(VAX)
326 #ifdef IEEE_Arith
327  if ((word0 (d) & Exp_mask) == Exp_mask)
328 #else
329  if (word0 (d) == 0x8000)
330 #endif
331  {
332  /* Infinity or NaN */
333  *decpt = 9999;
334  s =
335 #ifdef IEEE_Arith
336  !word1 (d) && !(word0 (d) & 0xfffff) ? "Infinity" :
337 #endif
338  "NaN";
339  if (rve)
340  *rve =
341 #ifdef IEEE_Arith
342  s[3] ? s + 8 :
343 #endif
344  s + 3;
345 
346 
347  return s;
348  }
349 
350 #ifdef IBM
351  d.d += 0; /* normalize */
352 #endif
353  if (!d.d)
354  {
355  *decpt = 1;
356  s = "0";
357  if (rve)
358  *rve = s + 1;
359 
360  return s;
361  }
362  #ifdef _SMALL_PRINTF
363  b = small_d2b (ptr, d.d, &be, &bbits,&tab_b[0]);
364  #else
365  b = small_d2b (ptr, d.d, &be, &bbits);
366  #endif
367 
368 #ifdef Sudden_Underflow
369  i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1));
370 #else
371  if ((i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1))) != 0)
372  {
373 #endif
374  d2.d = d.d;
375  word0 (d2) &= Frac_mask1;
376  word0 (d2) |= Exp_11;
377 #ifdef IBM
378  if (j = 11 - hi0bits (word0 (d2) & Frac_mask))
379  d2.d /= 1 << j;
380 #endif
381 
382  /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
383  * log10(x) = log(x) / log(10)
384  * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
385  * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
386  *
387  * This suggests computing an approximation k to log10(d) by
388  *
389  * k = (i - Bias)*0.301029995663981
390  * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
391  *
392  * We want k to be too large rather than too small.
393  * The error in the first-order Taylor series approximation
394  * is in our favor, so we just round up the constant enough
395  * to compensate for any error in the multiplication of
396  * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
397  * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
398  * adding 1e-13 to the constant term more than suffices.
399  * Hence we adjust the constant term to 0.1760912590558.
400  * (We could get a more accurate k by invoking log10,
401  * but this is probably not worthwhile.)
402  */
403 
404  i -= Bias;
405 #ifdef IBM
406  i <<= 2;
407  i += j;
408 #endif
409 #ifndef Sudden_Underflow
410  denorm = 0;
411  }
412  else
413  {
414  /* d is denormalized */
415 
416  i = bbits + be + (Bias + (P - 1) - 1);
417  x = (i > 32) ? (word0 (d) << (64 - i)) | (word1 (d) >> (i - 32))
418  : (word1 (d) << (32 - i));
419  d2.d = x;
420  word0 (d2) -= 31 * Exp_msk1; /* adjust exponent */
421  i -= (Bias + (P - 1) - 1) + 1;
422  denorm = 1;
423  }
424 #endif
425  ds = (d2.d - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981;
426  k = (int) ds;
427  if (ds < 0. && ds != k)
428  k--; /* want k = floor(ds) */
429  k_check = 1;
430  if (k >= 0 && k <= Ten_pmax)
431  {
432  if (d.d < small_tens[k])
433  k--;
434  k_check = 0;
435  }
436  j = bbits - i - 1;
437  if (j >= 0)
438  {
439  b2 = 0;
440  s2 = j;
441  }
442  else
443  {
444  b2 = -j;
445  s2 = 0;
446  }
447  if (k >= 0)
448  {
449  b5 = 0;
450  s5 = k;
451  s2 += k;
452  }
453  else
454  {
455  b2 -= k;
456  b5 = -k;
457  s5 = 0;
458  }
459  if (mode < 0 || mode > 9)
460  mode = 0;
461  try_quick = 1;
462  if (mode > 5)
463  {
464  mode -= 4;
465  try_quick = 0;
466  }
467  leftright = 1;
468  ilim = ilim1 = -1;
469  switch (mode)
470  {
471  case 0:
472  case 1:
473  i = 18;
474  ndigits = 0;
475  break;
476  case 2:
477  leftright = 0;
478  /* no break */
479  case 4:
480  if (ndigits <= 0)
481  ndigits = 1;
482  ilim = ilim1 = i = ndigits;
483  break;
484  case 3:
485  leftright = 0;
486  /* no break */
487  case 5:
488  i = ndigits + k + 1;
489  ilim = i;
490  ilim1 = i - 1;
491  if (i <= 0)
492  i = 1;
493  }
494  j = sizeof (__ULong);
495  #ifndef _SMALL_PRINTF
496  for (_REENT_MP_RESULT_K(ptr) = 0; sizeof (_Bigint) - sizeof (__ULong) + j <= i;
497  j <<= 1)
498  _REENT_MP_RESULT_K(ptr)++;
499  _REENT_MP_RESULT(ptr) = Balloc (ptr, _REENT_MP_RESULT_K(ptr));
500  s = s0 = (char *) _REENT_MP_RESULT(ptr);
501  #else
502  s = s0 = &tab_s0[0];
503  #endif
504 
505  if (ilim >= 0 && ilim <= Quick_max && try_quick)
506  {
507  /* Try to get by with floating-point arithmetic. */
508 
509  i = 0;
510  d2.d = d.d;
511  k0 = k;
512  ilim0 = ilim;
513  ieps = 2; /* conservative */
514  if (k > 0)
515  {
516  ds = small_tens[k & 0xf];
517  j = k >> 4;
518  if (j & Bletch)
519  {
520  /* prevent overflows */
521  j &= Bletch - 1;
522  d.d /= small_bigtens[n_bigtens - 1];
523  ieps++;
524  }
525  for (; j; j >>= 1, i++)
526  if (j & 1)
527  {
528  ieps++;
529  ds *= small_bigtens[i];
530  }
531  d.d /= ds;
532  }
533  else if ((j1 = -k) != 0)
534  {
535  d.d *= small_tens[j1 & 0xf];
536  for (j = j1 >> 4; j; j >>= 1, i++)
537  if (j & 1)
538  {
539  ieps++;
540  d.d *= small_bigtens[i];
541  }
542  }
543  if (k_check && d.d < 1. && ilim > 0)
544  {
545  if (ilim1 <= 0)
546  goto fast_failed;
547  ilim = ilim1;
548  k--;
549  d.d *= 10.;
550  ieps++;
551  }
552  eps.d = ieps * d.d + 7.;
553  word0 (eps) -= (P - 1) * Exp_msk1;
554  if (ilim == 0)
555  {
556  S = mhi = 0;
557  d.d -= 5.;
558  if (d.d > eps.d)
559  goto one_digit;
560  if (d.d < -eps.d)
561  goto no_digits;
562  goto fast_failed;
563  }
564 #ifndef No_leftright
565  if (leftright)
566  {
567  /* Use Steele & White method of only
568  * generating digits needed.
569  */
570  eps.d = 0.5 / small_tens[ilim - 1] - eps.d;
571  for (i = 0;;)
572  {
573  L = d.d;
574  d.d -= L;
575 
576  *s++ = '0' + (int) L;
577 
578  if (d.d < eps.d)
579  goto ret1;
580  if (1. - d.d < eps.d)
581  goto bump_up;
582  if (++i >= ilim)
583  break;
584  eps.d *= 10.;
585  d.d *= 10.;
586  }
587  }
588  else
589  {
590 #endif
591  /* Generate ilim digits, then fix them up. */
592  eps.d *= small_tens[ilim - 1];
593  for (i = 1;; i++, d.d *= 10.)
594  {
595  L = d.d;
596  d.d -= L;
597  *s++ = '0' + (int) L;
598  if (i == ilim)
599  {
600  if (d.d > 0.5 + eps.d)
601  goto bump_up;
602  else if (d.d < 0.5 - eps.d)
603  {
604  while (*--s == '0');
605  s++;
606  goto ret1;
607  }
608  break;
609  }
610  }
611 #ifndef No_leftright
612  }
613 #endif
614  fast_failed:
615  s = s0;
616  d.d = d2.d;
617  k = k0;
618  ilim = ilim0;
619  }
620 
621  /* Do we have a "small" integer? */
622 
623  if (be >= 0 && k <= Int_max)
624  {
625  /* Yes. */
626  ds = small_tens[k];
627  if (ndigits < 0 && ilim <= 0)
628  {
629  S = mhi = 0;
630  if (ilim < 0 || d.d <= 5 * ds)
631  goto no_digits;
632  goto one_digit;
633  }
634  for (i = 1;; i++)
635  {
636  L = d.d / ds;
637  d.d -= L * ds;
638 #ifdef Check_FLT_ROUNDS
639  /* If FLT_ROUNDS == 2, L will usually be high by 1 */
640  if (d.d < 0)
641  {
642  L--;
643  d.d += ds;
644  }
645 #endif
646 
647  *s++ = '0' + (int) L;
648 
649  if (i == ilim)
650  {
651  d.d += d.d;
652  if ((d.d > ds) || ((d.d == ds) && (L & 1)))
653  {
654  bump_up:
655 
656 
657 
658  while (*--s == '9')
659  if (s == s0)
660  {
661  k++;
662  *s = '0';
663  break;
664  }
665  ++*s++;
666 
667  }
668  break;
669  }
670  if (!(d.d *= 10.))
671  break;
672  }
673  goto ret1;
674  }
675 
676  m2 = b2;
677  m5 = b5;
678  mhi = mlo = 0;
679  if (leftright)
680  {
681  if (mode < 2)
682  {
683  i =
684 #ifndef Sudden_Underflow
685  denorm ? be + (Bias + (P - 1) - 1 + 1) :
686 #endif
687 #ifdef IBM
688  1 + 4 * P - 3 - bbits + ((bbits + be - 1) & 3);
689 #else
690  1 + P - bbits;
691 #endif
692  }
693  else
694  {
695  j = ilim - 1;
696  if (m5 >= j)
697  m5 -= j;
698  else
699  {
700  s5 += j -= m5;
701  b5 += j;
702  m5 = 0;
703  }
704  if ((i = ilim) < 0)
705  {
706  m2 -= i;
707  i = 0;
708  }
709  }
710  b2 += i;
711  s2 += i;
712 
713  #ifdef _SMALL_PRINTF
714  mhi = small_i2b (ptr, 1,&tab_mhi[0]);
715  #else
716  mhi=i2b(ptr,1);
717  #endif
718  }
719  if (m2 > 0 && s2 > 0)
720  {
721  i = m2 < s2 ? m2 : s2;
722  b2 -= i;
723  m2 -= i;
724  s2 -= i;
725  }
726  if (b5 > 0)
727  {
728  if (leftright)
729  {
730  if (m5 > 0)
731  {
732  #ifdef _SMALL_PRINTF
733  if (mhi == &tab_mhi[0]){
734  mhi = small_pow5mult (ptr, mhi, m5,&tab_mhilshift[0]);
735  }
736  else{
737  mhi = small_pow5mult (ptr, mhi, m5,&tab_mhi[0]);
738  }
739 
740  b1 = small_mult (ptr, mhi, b,&tab_b1[0]);
741  #else
742  mhi = pow5mult (ptr, mhi, m5);
743  b1 = mult (ptr, mhi, b);
744  Bfree (ptr, b);
745  #endif
746  }
747  if ((j = b5 - m5) != 0)
748  #ifdef _SMALL_PRINTF
749  if( b == &tab_b[0]){
750  b = small_pow5mult (ptr, b, b5,&tab_blshift[0]);
751  }
752  else{
753  b = small_pow5mult (ptr, b, b5,&tab_b[0]);
754  }
755  #else
756  b = pow5mult (ptr, b, j);
757  #endif
758 
759 
760 
761  }
762  else
763  #ifdef _SMALL_PRINTF
764  if( b == &tab_b[0]){
765  b = small_pow5mult (ptr, b, b5,&tab_blshift[0]);
766  }
767  else{
768  b = small_pow5mult (ptr, b, b5,&tab_b[0]);
769  }
770 
771  #else
772  b = pow5mult (ptr, b, b5);
773  #endif
774 
775  }
776  #ifdef _SMALL_PRINTF
777  S = small_i2b (ptr, 1,&tab_S[0]);
778  #else
779  S = small_i2b (ptr, 1);
780  #endif
781  if (s5 > 0)
782  #ifdef _SMALL_PRINTF
783  if (S == &tab_S[0]){
784  S = small_pow5mult (ptr, S, s5,&tab_Slshift[0]);
785  }
786  else{
787  S = small_pow5mult (ptr, S, s5,&tab_S[0]);
788  }
789 
790  #else
791  S = pow5mult (ptr, S, s5);
792  #endif
793 
794  /* Check for special case that d is a normalized power of 2. */
795 
796  spec_case = 0;
797  if (mode < 2)
798  {
799  if (!word1 (d) && !(word0 (d) & Bndry_mask)
800 #ifndef Sudden_Underflow
801  && word0 (d) & Exp_mask
802 #endif
803  )
804  {
805  /* The special case */
806  b2 += Log2P;
807  s2 += Log2P;
808  spec_case = 1;
809  }
810  }
811 
812  /* Arrange for convenient computation of quotients:
813  * shift left if necessary so divisor has 4 leading 0 bits.
814  *
815  * Perhaps we should just compute leading 28 bits of S once
816  * and for all and pass them and a shift to quorem, so it
817  * can do shifts and ors to compute the numerator for q.
818  */
819 
820 #ifdef Pack_32
821  if ((i = ((s5 ? 32 -small_hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0x1f) != 0)
822  i = 32 - i;
823 #else
824  if ((i = ((s5 ? 32 - small_hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0xf) != 0)
825  i = 16 - i;
826 #endif
827  if (i > 4)
828  {
829  i -= 4;
830  b2 += i;
831  m2 += i;
832  s2 += i;
833  }
834  else if (i < 4)
835  {
836  i += 28;
837  b2 += i;
838  m2 += i;
839  s2 += i;
840  }
841  if (b2 > 0)
842  #ifdef _SMALL_PRINTF
843  if (b==&tab_b[0]){
844  b = small_lshift (ptr, b, b2,&tab_blshift[0]);
845  }
846  else {
847  b = small_lshift (ptr, b, b2,&tab_b[0]);
848  }
849  #else
850  b = lshift (ptr, b, b2);
851  #endif
852  if (s2 > 0)
853  #ifdef _SMALL_PRINTF
854  if ( S == tab_S) {
855  S = small_lshift (ptr, S, s2,&tab_Slshift[0]);
856  }
857  else {
858  S = small_lshift (ptr, S, s2,&tab_S[0]);
859  }
860  #else
861  S = lshift (ptr, S, s2);
862  #endif
863  if (k_check)
864  {
865  if (small_cmp (b, S) < 0)
866  {
867  k--; /* we botched the k estimate */
868  #ifdef _SMALL_PRINTF
869  if (b == &tab_b[0] ){
870 
871  b = small_multadd (ptr, b, 10, 0,&tab_blshift[0]);
872  }
873  else{
874  b = small_multadd (ptr, b, 10, 0,&tab_b[0]);
875  }
876  #else
877  b = multadd (ptr, b, 10, 0);
878  #endif
879 
880 
881  if (leftright)
882  #ifdef _SMALL_PRINTF
883  if (mhi == &tab_mhi[0] ){
884 
885  mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhilshift[0]);
886  }
887  else{
888  mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhi[0]);
889  }
890  #else
891  mhi = multadd (ptr, mhi, 10, 0);
892  #endif
893  ilim = ilim1;
894  }
895  }
896  if (ilim <= 0 && mode > 2)
897  {
898  #ifdef _SMALL_PRINTF
899  _Bigint * tab;
900  if ( S == &tab_S[0] ){
901  tab = tab_Slshift;
902  }
903  else {
904  tab = tab_S;
905  }
906 
907  if (ilim < 0 || small_cmp (b, S = small_multadd (ptr, S, 5, 0,&tab[0])) <= 0)
908  {
909  #else
910  if (ilim < 0 || small_cmp (b, S = multadd (ptr, S, 5, 0)) <= 0)
911  {
912  #endif
913  /* no digits, fcvt style */
914  no_digits:
915  k = -1 - ndigits;
916  goto ret;
917  }
918  one_digit:
919  *s++ = '1';
920  k++;
921  goto ret;
922  }
923  if (leftright)
924  {
925  if (m2 > 0)
926  #ifdef _SMALL_PRINTF
927  if (mhi == &tab_mhi[0]){
928  mhi = small_lshift (ptr, mhi, m2,&tab_mhilshift[0]);
929  }
930  else {
931  mhi = small_lshift (ptr, mhi, m2,&tab_mhi[0]);
932  }
933 
934  #else
935  mhi = lshift (ptr, mhi, m2);
936  #endif
937  /* Compute mlo -- check for special case
938  * that d is a normalized power of 2.
939  */
940 
941  mlo = mhi;
942  if (spec_case)
943  {
944  #ifndef _SMALL_PRINTF
945 
946  mhi = Balloc (ptr, mhi->_k);
947 
948  #else
949  int sauv_k =mhi->_k;
950  mhi =&tab_mhi[0];
951  mhi->_k = sauv_k;
952  mhi->_maxwds = (1<<sauv_k);
953  mhi->_sign = mhi->_wds =0 ;
954  #endif
955  Bcopy (mhi, mlo);
956 
957  #ifdef _SMALL_PRINTF
958  if( mhi == &tab_mhi[0]){
959  mhi = small_lshift (ptr, mhi, Log2P,&tab_mhilshift[0]);
960  }
961  else {
962  mhi = small_lshift (ptr, mhi, Log2P,&tab_mhi[0]);
963  }
964  #else
965  mhi = lshift (ptr, mhi, Log2P);
966  #endif
967  }
968 
969  for (i = 1;; i++)
970  {
971  dig = quorem (b, S) + '0';
972  /* Do we yet have the shortest decimal string
973  * that will round to d?
974  */
975  j = small_cmp (b, mlo);
976  #ifdef _SMALL_PRINTF
977  delta = small_diff (ptr, S, mhi,&tab_delta[0]);
978  #else
979  delta = diff (ptr, S, mhi);
980  #endif
981  j1 = delta->_sign ? 1 : small_cmp (b, delta);
982  #ifndef _SMALL_PRINTF
983  Bfree (ptr, delta);
984  #endif
985 #ifndef ROUND_BIASED
986  if (j1 == 0 && !mode && !(word1 (d) & 1))
987  {
988  if (dig == '9')
989  goto round_9_up;
990  if (j > 0)
991  dig++;
992 
993  *s++ = dig;
994 
995  goto ret;
996  }
997 #endif
998  if ((j < 0) || ((j == 0) && !mode
999 #ifndef ROUND_BIASED
1000  && !(word1 (d) & 1)
1001 #endif
1002  ))
1003  {
1004  if (j1 > 0)
1005  {
1006 
1007  #ifdef _SMALL_PRINTF
1008  if (b == &tab_b[0]){
1009  b = small_lshift (ptr, b, 1,&tab_blshift[0]);
1010  }
1011  else {
1012  b = small_lshift (ptr, b, 1,&tab_b[0]);
1013  }
1014  #else
1015  b = lshift (ptr, b, 1);
1016  #endif
1017 
1018  j1 = small_cmp (b, S);
1019  if (((j1 > 0) || ((j1 == 0) && (dig & 1)))
1020  && dig++ == '9')
1021  goto round_9_up;
1022  }
1023 
1024  *s++ = dig;
1025 
1026  goto ret;
1027  }
1028  if (j1 > 0)
1029  {
1030  if (dig == '9')
1031  { /* possible if i == 1 */
1032  round_9_up:
1033 
1034  *s++ = '9';
1035 
1036  goto roundoff;
1037  }
1038 
1039  *s++ = dig+1;
1040 
1041  goto ret;
1042  }
1043 
1044  *s++ = dig;
1045 
1046  if (i == ilim)
1047  break;
1048  #ifdef _SMALL_PRINTF
1049  if (b == tab_b ){
1050  b = small_multadd (ptr, b, 10, 0,&tab_blshift[0]);
1051  }
1052  else{
1053  b = small_multadd (ptr, b, 10, 0,&tab_b[0]);
1054  }
1055 
1056  #else
1057  b = multadd (ptr, b, 10, 0);
1058  #endif
1059 
1060 
1061  if (mlo == mhi)
1062  #ifdef _SMALL_PRINTF
1063  if ( mhi = &tab_mhi[0] ) {
1064  mlo = mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhilshift[0]);
1065  }
1066  else{
1067  mlo = mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhi[0]);
1068  }
1069 
1070  #else
1071  mlo = mhi = multadd (ptr, mhi, 10, 0);
1072  #endif
1073  else
1074  {
1075 
1076  #ifdef _SMALL_PRINTF
1077  if ( mlo = &tab_mhi[0] ) {
1078  mlo = small_multadd (ptr, mlo, 10, 0,&tab_mlolshift[0]);
1079  }
1080  else{
1081  mlo = small_multadd (ptr, mlo, 10, 0,&tab_mlo[0]);
1082  }
1083  if ( mhi = &tab_mhi[0] ) {
1084  mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhilshift[0]);
1085  }
1086  else{
1087  mhi = small_multadd (ptr, mhi, 10, 0,&tab_mhi[0]);
1088  }
1089  #else
1090  mlo = multadd (ptr, mlo, 10, 0);
1091  mhi = multadd (ptr, mhi, 10, 0);
1092  #endif
1093  }
1094  }
1095  }
1096  else
1097  for (i = 1;; i++)
1098  {
1099 
1100  *s++ = dig =quorem (b, S) + '0';
1101 
1102 
1103  if (i >= ilim)
1104  break;
1105  #ifdef _SMALL_PRINTF
1106  if ( b == &tab_b[0] ) {
1107  b = small_multadd (ptr, b, 10, 0,&tab_blshift[0]);
1108  }
1109  else {
1110  b = small_multadd (ptr, b, 10, 0,&tab_b[0]);
1111  }
1112  #else
1113  b = multadd (ptr, b, 10, 0);
1114  #endif
1115  }
1116 
1117  /* Round off last digit */
1118  #ifdef _SMALL_PRINTF
1119  if (b == &tab_b[0]) {
1120  b = small_lshift (ptr, b, 1,&tab_blshift[0]);
1121  }
1122  else {
1123  b = small_lshift (ptr, b, 1,&tab_b[0]);
1124  }
1125  #else
1126  b = lshift (ptr, b, 1);
1127  #endif
1128 
1129  j = small_cmp (b, S);
1130  if ((j > 0) || ((j == 0) && (dig & 1)))
1131  {
1132  roundoff:
1133 
1134 
1135  while (*--s == '9')
1136  if (s == s0)
1137  {
1138  k++;
1139  *s++ = '1';
1140  goto ret;
1141  }
1142  ++*s++;
1143  }
1144  else
1145  {
1146  while (*--s == '0');
1147  s++;
1148  }
1149 
1150 
1151 
1152 ret:
1153  #ifndef _SMALL_PRINTF
1154  Bfree (ptr, S);
1155 
1156  if (mhi)
1157  {
1158  if (mlo && mlo != mhi)
1159  Bfree (ptr, mlo);
1160  Bfree (ptr, mhi);
1161  }
1162  #endif
1163 ret1:
1164  #ifndef _SMALL_PRINTF
1165  Bfree (ptr, b);
1166  #endif
1167  *s = 0;
1168  #endif
1169  *decpt = k + 1;
1170  if (rve)
1171  *rve = s;
1172  return s0;
1173 }
1174