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