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