/****************************************************************12The author of this software is David M. Gay.34Copyright (C) 1998, 1999 by Lucent Technologies5All Rights Reserved67Permission to use, copy, modify, and distribute this software and8its documentation for any purpose and without fee is hereby9granted, provided that the above copyright notice appear in all10copies and that both that the copyright notice and this11permission notice and warranty disclaimer appear in supporting12documentation, and that the name of Lucent or any of its entities13not be used in advertising or publicity pertaining to14distribution of the software without specific, written prior15permission.1617LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,18INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.19IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY20SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES21WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER22IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,23ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF24THIS SOFTWARE.2526****************************************************************/2728/* Please send bug reports to David M. Gay (dmg at acm dot org,29* with " at " changed at "@" and " dot " changed to "."). */3031#include "gdtoaimp.h"3233/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.34*35* Inspired by "How to Print Floating-Point Numbers Accurately" by36* Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].37*38* Modifications:39* 1. Rather than iterating, we use a simple numeric overestimate40* to determine k = floor(log10(d)). We scale relevant41* quantities using O(log2(k)) rather than O(k) multiplications.42* 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't43* try to generate digits strictly left to right. Instead, we44* compute with fewer bits and propagate the carry if necessary45* when rounding the final digit up. This is often faster.46* 3. Under the assumption that input will be rounded nearest,47* mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.48* That is, we allow equality in stopping tests when the49* round-nearest rule will give the same floating-point value50* as would satisfaction of the stopping test with strict51* inequality.52* 4. We remove common factors of powers of 2 from relevant53* quantities.54* 5. When converting floating-point integers less than 1e16,55* we use floating-point arithmetic rather than resorting56* to multiple-precision integers.57* 6. When asked to produce fewer than 15 digits, we first try58* to get by with floating-point arithmetic; we resort to59* multiple-precision integer arithmetic only if we cannot60* guarantee that the floating-point calculation has given61* the correctly rounded result. For k requested digits and62* "uniformly" distributed input, the probability is63* something like 10^(k-15) that we must resort to the Long64* calculation.65*/6667#ifdef Honor_FLT_ROUNDS68#undef Check_FLT_ROUNDS69#define Check_FLT_ROUNDS70#else71#define Rounding Flt_Rounds72#endif7374char *75dtoa76#ifdef KR_headers77(d0, mode, ndigits, decpt, sign, rve)78double d0; int mode, ndigits, *decpt, *sign; char **rve;79#else80(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)81#endif82{83/* Arguments ndigits, decpt, sign are similar to those84of ecvt and fcvt; trailing zeros are suppressed from85the returned string. If not null, *rve is set to point86to the end of the return value. If d is +-Infinity or NaN,87then *decpt is set to 9999.8889mode:900 ==> shortest string that yields d when read in91and rounded to nearest.921 ==> like 0, but with Steele & White stopping rule;93e.g. with IEEE P754 arithmetic , mode 0 gives941e23 whereas mode 1 gives 9.999999999999999e22.952 ==> max(1,ndigits) significant digits. This gives a96return value similar to that of ecvt, except97that trailing zeros are suppressed.983 ==> through ndigits past the decimal point. This99gives a return value similar to that from fcvt,100except that trailing zeros are suppressed, and101ndigits can be negative.1024,5 ==> similar to 2 and 3, respectively, but (in103round-nearest mode) with the tests of mode 0 to104possibly return a shorter string that rounds to d.105With IEEE arithmetic and compilation with106-DHonor_FLT_ROUNDS, modes 4 and 5 behave the same107as modes 2 and 3 when FLT_ROUNDS != 1.1086-9 ==> Debugging modes similar to mode - 4: don't try109fast floating-point estimate (if applicable).110111Values of mode other than 0-9 are treated as mode 0.112113Sufficient space is allocated to the return value114to hold the suppressed trailing zeros.115*/116117int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,118j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,119spec_case, try_quick;120Long L;121#ifndef Sudden_Underflow122int denorm;123ULong x;124#endif125Bigint *b, *b1, *delta, *mlo, *mhi, *S;126U d, d2, eps;127double ds;128char *s, *s0;129#ifdef SET_INEXACT130int inexact, oldinexact;131#endif132#ifdef Honor_FLT_ROUNDS /*{*/133int Rounding;134#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */135Rounding = Flt_Rounds;136#else /*}{*/137Rounding = 1;138switch(fegetround()) {139case FE_TOWARDZERO: Rounding = 0; break;140case FE_UPWARD: Rounding = 2; break;141case FE_DOWNWARD: Rounding = 3;142}143#endif /*}}*/144#endif /*}*/145146#ifndef MULTIPLE_THREADS147if (dtoa_result) {148freedtoa(dtoa_result);149dtoa_result = 0;150}151#endif152d.d = d0;153if (word0(&d) & Sign_bit) {154/* set sign for everything, including 0's and NaNs */155*sign = 1;156word0(&d) &= ~Sign_bit; /* clear sign bit */157}158else159*sign = 0;160161#if defined(IEEE_Arith) + defined(VAX)162#ifdef IEEE_Arith163if ((word0(&d) & Exp_mask) == Exp_mask)164#else165if (word0(&d) == 0x8000)166#endif167{168/* Infinity or NaN */169*decpt = 9999;170#ifdef IEEE_Arith171if (!word1(&d) && !(word0(&d) & 0xfffff))172return nrv_alloc("Infinity", rve, 8);173#endif174return nrv_alloc("NaN", rve, 3);175}176#endif177#ifdef IBM178dval(&d) += 0; /* normalize */179#endif180if (!dval(&d)) {181*decpt = 1;182return nrv_alloc("0", rve, 1);183}184185#ifdef SET_INEXACT186try_quick = oldinexact = get_inexact();187inexact = 1;188#endif189#ifdef Honor_FLT_ROUNDS190if (Rounding >= 2) {191if (*sign)192Rounding = Rounding == 2 ? 0 : 2;193else194if (Rounding != 2)195Rounding = 0;196}197#endif198199b = d2b(dval(&d), &be, &bbits);200#ifdef Sudden_Underflow201i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));202#else203if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {204#endif205dval(&d2) = dval(&d);206word0(&d2) &= Frac_mask1;207word0(&d2) |= Exp_11;208#ifdef IBM209if (( j = 11 - hi0bits(word0(&d2) & Frac_mask) )!=0)210dval(&d2) /= 1 << j;211#endif212213/* log(x) ~=~ log(1.5) + (x-1.5)/1.5214* log10(x) = log(x) / log(10)215* ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))216* log10(&d) = (i-Bias)*log(2)/log(10) + log10(&d2)217*218* This suggests computing an approximation k to log10(&d) by219*220* k = (i - Bias)*0.301029995663981221* + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );222*223* We want k to be too large rather than too small.224* The error in the first-order Taylor series approximation225* is in our favor, so we just round up the constant enough226* to compensate for any error in the multiplication of227* (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,228* and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,229* adding 1e-13 to the constant term more than suffices.230* Hence we adjust the constant term to 0.1760912590558.231* (We could get a more accurate k by invoking log10,232* but this is probably not worthwhile.)233*/234235i -= Bias;236#ifdef IBM237i <<= 2;238i += j;239#endif240#ifndef Sudden_Underflow241denorm = 0;242}243else {244/* d is denormalized */245246i = bbits + be + (Bias + (P-1) - 1);247x = i > 32 ? word0(&d) << (64 - i) | word1(&d) >> (i - 32)248: word1(&d) << (32 - i);249dval(&d2) = x;250word0(&d2) -= 31*Exp_msk1; /* adjust exponent */251i -= (Bias + (P-1) - 1) + 1;252denorm = 1;253}254#endif255ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;256k = (int)ds;257if (ds < 0. && ds != k)258k--; /* want k = floor(ds) */259k_check = 1;260if (k >= 0 && k <= Ten_pmax) {261if (dval(&d) < tens[k])262k--;263k_check = 0;264}265j = bbits - i - 1;266if (j >= 0) {267b2 = 0;268s2 = j;269}270else {271b2 = -j;272s2 = 0;273}274if (k >= 0) {275b5 = 0;276s5 = k;277s2 += k;278}279else {280b2 -= k;281b5 = -k;282s5 = 0;283}284if (mode < 0 || mode > 9)285mode = 0;286287#ifndef SET_INEXACT288#ifdef Check_FLT_ROUNDS289try_quick = Rounding == 1;290#else291try_quick = 1;292#endif293#endif /*SET_INEXACT*/294295if (mode > 5) {296mode -= 4;297try_quick = 0;298}299leftright = 1;300ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */301/* silence erroneous "gcc -Wall" warning. */302switch(mode) {303case 0:304case 1:305i = 18;306ndigits = 0;307break;308case 2:309leftright = 0;310/* no break */311case 4:312if (ndigits <= 0)313ndigits = 1;314ilim = ilim1 = i = ndigits;315break;316case 3:317leftright = 0;318/* no break */319case 5:320i = ndigits + k + 1;321ilim = i;322ilim1 = i - 1;323if (i <= 0)324i = 1;325}326s = s0 = rv_alloc(i);327328#ifdef Honor_FLT_ROUNDS329if (mode > 1 && Rounding != 1)330leftright = 0;331#endif332333if (ilim >= 0 && ilim <= Quick_max && try_quick) {334335/* Try to get by with floating-point arithmetic. */336337i = 0;338dval(&d2) = dval(&d);339k0 = k;340ilim0 = ilim;341ieps = 2; /* conservative */342if (k > 0) {343ds = tens[k&0xf];344j = k >> 4;345if (j & Bletch) {346/* prevent overflows */347j &= Bletch - 1;348dval(&d) /= bigtens[n_bigtens-1];349ieps++;350}351for(; j; j >>= 1, i++)352if (j & 1) {353ieps++;354ds *= bigtens[i];355}356dval(&d) /= ds;357}358else if (( j1 = -k )!=0) {359dval(&d) *= tens[j1 & 0xf];360for(j = j1 >> 4; j; j >>= 1, i++)361if (j & 1) {362ieps++;363dval(&d) *= bigtens[i];364}365}366if (k_check && dval(&d) < 1. && ilim > 0) {367if (ilim1 <= 0)368goto fast_failed;369ilim = ilim1;370k--;371dval(&d) *= 10.;372ieps++;373}374dval(&eps) = ieps*dval(&d) + 7.;375word0(&eps) -= (P-1)*Exp_msk1;376if (ilim == 0) {377S = mhi = 0;378dval(&d) -= 5.;379if (dval(&d) > dval(&eps))380goto one_digit;381if (dval(&d) < -dval(&eps))382goto no_digits;383goto fast_failed;384}385#ifndef No_leftright386if (leftright) {387/* Use Steele & White method of only388* generating digits needed.389*/390dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);391for(i = 0;;) {392L = dval(&d);393dval(&d) -= L;394*s++ = '0' + (int)L;395if (dval(&d) < dval(&eps))396goto ret1;397if (1. - dval(&d) < dval(&eps))398goto bump_up;399if (++i >= ilim)400break;401dval(&eps) *= 10.;402dval(&d) *= 10.;403}404}405else {406#endif407/* Generate ilim digits, then fix them up. */408dval(&eps) *= tens[ilim-1];409for(i = 1;; i++, dval(&d) *= 10.) {410L = (Long)(dval(&d));411if (!(dval(&d) -= L))412ilim = i;413*s++ = '0' + (int)L;414if (i == ilim) {415if (dval(&d) > 0.5 + dval(&eps))416goto bump_up;417else if (dval(&d) < 0.5 - dval(&eps)) {418while(*--s == '0');419s++;420goto ret1;421}422break;423}424}425#ifndef No_leftright426}427#endif428fast_failed:429s = s0;430dval(&d) = dval(&d2);431k = k0;432ilim = ilim0;433}434435/* Do we have a "small" integer? */436437if (be >= 0 && k <= Int_max) {438/* Yes. */439ds = tens[k];440if (ndigits < 0 && ilim <= 0) {441S = mhi = 0;442if (ilim < 0 || dval(&d) <= 5*ds)443goto no_digits;444goto one_digit;445}446for(i = 1;; i++, dval(&d) *= 10.) {447L = (Long)(dval(&d) / ds);448dval(&d) -= L*ds;449#ifdef Check_FLT_ROUNDS450/* If FLT_ROUNDS == 2, L will usually be high by 1 */451if (dval(&d) < 0) {452L--;453dval(&d) += ds;454}455#endif456*s++ = '0' + (int)L;457if (!dval(&d)) {458#ifdef SET_INEXACT459inexact = 0;460#endif461break;462}463if (i == ilim) {464#ifdef Honor_FLT_ROUNDS465if (mode > 1)466switch(Rounding) {467case 0: goto ret1;468case 2: goto bump_up;469}470#endif471dval(&d) += dval(&d);472#ifdef ROUND_BIASED473if (dval(&d) >= ds)474#else475if (dval(&d) > ds || (dval(&d) == ds && L & 1))476#endif477{478bump_up:479while(*--s == '9')480if (s == s0) {481k++;482*s = '0';483break;484}485++*s++;486}487break;488}489}490goto ret1;491}492493m2 = b2;494m5 = b5;495mhi = mlo = 0;496if (leftright) {497i =498#ifndef Sudden_Underflow499denorm ? be + (Bias + (P-1) - 1 + 1) :500#endif501#ifdef IBM5021 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);503#else5041 + P - bbits;505#endif506b2 += i;507s2 += i;508mhi = i2b(1);509}510if (m2 > 0 && s2 > 0) {511i = m2 < s2 ? m2 : s2;512b2 -= i;513m2 -= i;514s2 -= i;515}516if (b5 > 0) {517if (leftright) {518if (m5 > 0) {519mhi = pow5mult(mhi, m5);520b1 = mult(mhi, b);521Bfree(b);522b = b1;523}524if (( j = b5 - m5 )!=0)525b = pow5mult(b, j);526}527else528b = pow5mult(b, b5);529}530S = i2b(1);531if (s5 > 0)532S = pow5mult(S, s5);533534/* Check for special case that d is a normalized power of 2. */535536spec_case = 0;537if ((mode < 2 || leftright)538#ifdef Honor_FLT_ROUNDS539&& Rounding == 1540#endif541) {542if (!word1(&d) && !(word0(&d) & Bndry_mask)543#ifndef Sudden_Underflow544&& word0(&d) & (Exp_mask & ~Exp_msk1)545#endif546) {547/* The special case */548b2 += Log2P;549s2 += Log2P;550spec_case = 1;551}552}553554/* Arrange for convenient computation of quotients:555* shift left if necessary so divisor has 4 leading 0 bits.556*557* Perhaps we should just compute leading 28 bits of S once558* and for all and pass them and a shift to quorem, so it559* can do shifts and ors to compute the numerator for q.560*/561#ifdef Pack_32562if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0)563i = 32 - i;564#else565if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0)566i = 16 - i;567#endif568if (i > 4) {569i -= 4;570b2 += i;571m2 += i;572s2 += i;573}574else if (i < 4) {575i += 28;576b2 += i;577m2 += i;578s2 += i;579}580if (b2 > 0)581b = lshift(b, b2);582if (s2 > 0)583S = lshift(S, s2);584if (k_check) {585if (cmp(b,S) < 0) {586k--;587b = multadd(b, 10, 0); /* we botched the k estimate */588if (leftright)589mhi = multadd(mhi, 10, 0);590ilim = ilim1;591}592}593if (ilim <= 0 && (mode == 3 || mode == 5)) {594if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {595/* no digits, fcvt style */596no_digits:597k = -1 - ndigits;598goto ret;599}600one_digit:601*s++ = '1';602k++;603goto ret;604}605if (leftright) {606if (m2 > 0)607mhi = lshift(mhi, m2);608609/* Compute mlo -- check for special case610* that d is a normalized power of 2.611*/612613mlo = mhi;614if (spec_case) {615mhi = Balloc(mhi->k);616Bcopy(mhi, mlo);617mhi = lshift(mhi, Log2P);618}619620for(i = 1;;i++) {621dig = quorem(b,S) + '0';622/* Do we yet have the shortest decimal string623* that will round to d?624*/625j = cmp(b, mlo);626delta = diff(S, mhi);627j1 = delta->sign ? 1 : cmp(b, delta);628Bfree(delta);629#ifndef ROUND_BIASED630if (j1 == 0 && mode != 1 && !(word1(&d) & 1)631#ifdef Honor_FLT_ROUNDS632&& Rounding >= 1633#endif634) {635if (dig == '9')636goto round_9_up;637if (j > 0)638dig++;639#ifdef SET_INEXACT640else if (!b->x[0] && b->wds <= 1)641inexact = 0;642#endif643*s++ = dig;644goto ret;645}646#endif647if (j < 0 || (j == 0 && mode != 1648#ifndef ROUND_BIASED649&& !(word1(&d) & 1)650#endif651)) {652if (!b->x[0] && b->wds <= 1) {653#ifdef SET_INEXACT654inexact = 0;655#endif656goto accept_dig;657}658#ifdef Honor_FLT_ROUNDS659if (mode > 1)660switch(Rounding) {661case 0: goto accept_dig;662case 2: goto keep_dig;663}664#endif /*Honor_FLT_ROUNDS*/665if (j1 > 0) {666b = lshift(b, 1);667j1 = cmp(b, S);668#ifdef ROUND_BIASED669if (j1 >= 0 /*)*/670#else671if ((j1 > 0 || (j1 == 0 && dig & 1))672#endif673&& dig++ == '9')674goto round_9_up;675}676accept_dig:677*s++ = dig;678goto ret;679}680if (j1 > 0) {681#ifdef Honor_FLT_ROUNDS682if (!Rounding)683goto accept_dig;684#endif685if (dig == '9') { /* possible if i == 1 */686round_9_up:687*s++ = '9';688goto roundoff;689}690*s++ = dig + 1;691goto ret;692}693#ifdef Honor_FLT_ROUNDS694keep_dig:695#endif696*s++ = dig;697if (i == ilim)698break;699b = multadd(b, 10, 0);700if (mlo == mhi)701mlo = mhi = multadd(mhi, 10, 0);702else {703mlo = multadd(mlo, 10, 0);704mhi = multadd(mhi, 10, 0);705}706}707}708else709for(i = 1;; i++) {710*s++ = dig = quorem(b,S) + '0';711if (!b->x[0] && b->wds <= 1) {712#ifdef SET_INEXACT713inexact = 0;714#endif715goto ret;716}717if (i >= ilim)718break;719b = multadd(b, 10, 0);720}721722/* Round off last digit */723724#ifdef Honor_FLT_ROUNDS725switch(Rounding) {726case 0: goto trimzeros;727case 2: goto roundoff;728}729#endif730b = lshift(b, 1);731j = cmp(b, S);732#ifdef ROUND_BIASED733if (j >= 0)734#else735if (j > 0 || (j == 0 && dig & 1))736#endif737{738roundoff:739while(*--s == '9')740if (s == s0) {741k++;742*s++ = '1';743goto ret;744}745++*s++;746}747else {748#ifdef Honor_FLT_ROUNDS749trimzeros:750#endif751while(*--s == '0');752s++;753}754ret:755Bfree(S);756if (mhi) {757if (mlo && mlo != mhi)758Bfree(mlo);759Bfree(mhi);760}761ret1:762#ifdef SET_INEXACT763if (inexact) {764if (!oldinexact) {765word0(&d) = Exp_1 + (70 << Exp_shift);766word1(&d) = 0;767dval(&d) += 1.;768}769}770else if (!oldinexact)771clear_inexact();772#endif773Bfree(b);774*s = 0;775*decpt = k + 1;776if (rve)777*rve = s;778return s0;779}780781782