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