Contiki 2.6
|
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