⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsdtoa.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    ULong borrow, carry, y, ys;    ULong si, z, zs;#endif    n = S->wds;    JS_ASSERT(b->wds <= n);    if (b->wds < n)        return 0;    sx = S->x;    sxe = sx + --n;    bx = b->x;    bxe = bx + n;    JS_ASSERT(*sxe <= 0x7FFFFFFF);    q = *bxe / (*sxe + 1);  /* ensure q <= true quotient */    JS_ASSERT(q < 36);    if (q) {        borrow = 0;        carry = 0;        do {#ifdef ULLong            ys = *sx++ * (ULLong)q + carry;            carry = ys >> 32;            y = *bx - (ys & 0xffffffffUL) - borrow;            borrow = y >> 32 & 1UL;            *bx++ = (ULong)(y & 0xffffffffUL);#else            si = *sx++;            ys = (si & 0xffff) * q + carry;            zs = (si >> 16) * q + (ys >> 16);            carry = zs >> 16;            y = (*bx & 0xffff) - (ys & 0xffff) - borrow;            borrow = (y & 0x10000) >> 16;            z = (*bx >> 16) - (zs & 0xffff) - borrow;            borrow = (z & 0x10000) >> 16;            Storeinc(bx, z, y);#endif        }        while(sx <= sxe);        if (!*bxe) {            bx = b->x;            while(--bxe > bx && !*bxe)                --n;            b->wds = n;        }    }    if (cmp(b, S) >= 0) {        q++;        borrow = 0;        carry = 0;        bx = b->x;        sx = S->x;        do {#ifdef ULLong            ys = *sx++ + carry;            carry = ys >> 32;            y = *bx - (ys & 0xffffffffUL) - borrow;            borrow = y >> 32 & 1UL;            *bx++ = (ULong)(y & 0xffffffffUL);#else            si = *sx++;            ys = (si & 0xffff) + carry;            zs = (si >> 16) + (ys >> 16);            carry = zs >> 16;            y = (*bx & 0xffff) - (ys & 0xffff) - borrow;            borrow = (y & 0x10000) >> 16;            z = (*bx >> 16) - (zs & 0xffff) - borrow;            borrow = (z & 0x10000) >> 16;            Storeinc(bx, z, y);#endif        } while(sx <= sxe);        bx = b->x;        bxe = bx + n;        if (!*bxe) {            while(--bxe > bx && !*bxe)                --n;            b->wds = n;        }    }    return (int32)q;}/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. * * Inspired by "How to Print Floating-Point Numbers Accurately" by * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. * * Modifications: *  1. Rather than iterating, we use a simple numeric overestimate *     to determine k = floor(log10(d)).  We scale relevant *     quantities using O(log2(k)) rather than O(k) multiplications. *  2. For some modes > 2 (corresponding to ecvt and fcvt), we don't *     try to generate digits strictly left to right.  Instead, we *     compute with fewer bits and propagate the carry if necessary *     when rounding the final digit up.  This is often faster. *  3. Under the assumption that input will be rounded nearest, *     mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. *     That is, we allow equality in stopping tests when the *     round-nearest rule will give the same floating-point value *     as would satisfaction of the stopping test with strict *     inequality. *  4. We remove common factors of powers of 2 from relevant *     quantities. *  5. When converting floating-point integers less than 1e16, *     we use floating-point arithmetic rather than resorting *     to multiple-precision integers. *  6. When asked to produce fewer than 15 digits, we first try *     to get by with floating-point arithmetic; we resort to *     multiple-precision integer arithmetic only if we cannot *     guarantee that the floating-point calculation has given *     the correctly rounded result.  For k requested digits and *     "uniformly" distributed input, the probability is *     something like 10^(k-15) that we must resort to the Long *     calculation. *//* Always emits at least one digit. *//* If biasUp is set, then rounding in modes 2 and 3 will round away from zero * when the number is exactly halfway between two representable values.  For example, * rounding 2.5 to zero digits after the decimal point will return 3 and not 2. * 2.49 will still round to 2, and 2.51 will still round to 3. *//* bufsize should be at least 20 for modes 0 and 1.  For the other modes, * bufsize should be two greater than the maximum number of output characters expected. */static JSBooljs_dtoa(double d, int mode, JSBool biasUp, int ndigits,    int *decpt, int *sign, char **rve, char *buf, size_t bufsize){    /*  Arguments ndigits, decpt, sign are similar to those        of ecvt and fcvt; trailing zeros are suppressed from        the returned string.  If not null, *rve is set to point        to the end of the return value.  If d is +-Infinity or NaN,        then *decpt is set to 9999.        mode:        0 ==> shortest string that yields d when read in        and rounded to nearest.        1 ==> like 0, but with Steele & White stopping rule;        e.g. with IEEE P754 arithmetic , mode 0 gives        1e23 whereas mode 1 gives 9.999999999999999e22.        2 ==> max(1,ndigits) significant digits.  This gives a        return value similar to that of ecvt, except        that trailing zeros are suppressed.        3 ==> through ndigits past the decimal point.  This        gives a return value similar to that from fcvt,        except that trailing zeros are suppressed, and        ndigits can be negative.        4-9 should give the same return values as 2-3, i.e.,        4 <= mode <= 9 ==> same return as mode        2 + (mode & 1).  These modes are mainly for        debugging; often they run slower but sometimes        faster than modes 2-3.        4,5,8,9 ==> left-to-right digit generation.        6-9 ==> don't try fast floating-point estimate        (if applicable).        Values of mode other than 0-9 are treated as mode 0.        Sufficient space is allocated to the return value        to hold the suppressed trailing zeros.    */    int32 bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,        j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,        spec_case, try_quick;    Long L;#ifndef Sudden_Underflow    int32 denorm;    ULong x;#endif    Bigint *b, *b1, *delta, *mlo, *mhi, *S;    double d2, ds, eps;    char *s;    if (word0(d) & Sign_bit) {        /* set sign for everything, including 0's and NaNs */        *sign = 1;        set_word0(d, word0(d) & ~Sign_bit);  /* clear sign bit */    }    else        *sign = 0;    if ((word0(d) & Exp_mask) == Exp_mask) {        /* Infinity or NaN */        *decpt = 9999;        s = !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN";        if ((s[0] == 'I' && bufsize < 9) || (s[0] == 'N' && bufsize < 4)) {            JS_ASSERT(JS_FALSE);/*          JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */            return JS_FALSE;        }        strcpy(buf, s);        if (rve) {            *rve = buf[3] ? buf + 8 : buf + 3;            JS_ASSERT(**rve == '\0');        }        return JS_TRUE;    }    b = NULL;                           /* initialize for abort protection */    S = NULL;    mlo = mhi = NULL;    if (!d) {      no_digits:        *decpt = 1;        if (bufsize < 2) {            JS_ASSERT(JS_FALSE);/*          JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */            return JS_FALSE;        }        buf[0] = '0'; buf[1] = '\0';  /* copy "0" to buffer */        if (rve)            *rve = buf + 1;        /* We might have jumped to "no_digits" from below, so we need         * to be sure to free the potentially allocated Bigints to avoid         * memory leaks. */        Bfree(b);        Bfree(S);        if (mlo != mhi)            Bfree(mlo);        Bfree(mhi);        return JS_TRUE;    }    b = d2b(d, &be, &bbits);    if (!b)        goto nomem;#ifdef Sudden_Underflow    i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));#else    if ((i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {#endif        d2 = d;        set_word0(d2, word0(d2) & Frac_mask1);        set_word0(d2, word0(d2) | Exp_11);        /* log(x)   ~=~ log(1.5) + (x-1.5)/1.5         * log10(x)  =  log(x) / log(10)         *      ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))         * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)         *         * This suggests computing an approximation k to log10(d) by         *         * k = (i - Bias)*0.301029995663981         *  + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );         *         * We want k to be too large rather than too small.         * The error in the first-order Taylor series approximation         * is in our favor, so we just round up the constant enough         * to compensate for any error in the multiplication of         * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,         * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,         * adding 1e-13 to the constant term more than suffices.         * Hence we adjust the constant term to 0.1760912590558.         * (We could get a more accurate k by invoking log10,         *  but this is probably not worthwhile.)         */        i -= Bias;#ifndef Sudden_Underflow        denorm = 0;    }    else {        /* d is denormalized */        i = bbits + be + (Bias + (P-1) - 1);        x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) : word1(d) << (32 - i);        d2 = x;        set_word0(d2, word0(d2) - 31*Exp_msk1); /* adjust exponent */        i -= (Bias + (P-1) - 1) + 1;        denorm = 1;    }#endif    /* At this point d = f*2^i, where 1 <= f < 2.  d2 is an approximation of f. */    ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;    k = (int32)ds;    if (ds < 0. && ds != k)        k--;    /* want k = floor(ds) */    k_check = 1;    if (k >= 0 && k <= Ten_pmax) {        if (d < tens[k])            k--;        k_check = 0;    }    /* At this point floor(log10(d)) <= k <= floor(log10(d))+1.       If k_check is zero, we're guaranteed that k = floor(log10(d)). */    j = bbits - i - 1;    /* At this point d = b/2^j, where b is an odd integer. */    if (j >= 0) {        b2 = 0;        s2 = j;    }    else {        b2 = -j;        s2 = 0;    }    if (k >= 0) {        b5 = 0;        s5 = k;        s2 += k;    }    else {        b2 -= k;        b5 = -k;        s5 = 0;    }    /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer,       b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */    if (mode < 0 || mode > 9)        mode = 0;    try_quick = 1;    if (mode > 5) {        mode -= 4;        try_quick = 0;    }    leftright = 1;    ilim = ilim1 = 0;    switch(mode) {    case 0:    case 1:        ilim = ilim1 = -1;        i = 18;        ndigits = 0;        break;    case 2:        leftright = 0;        /* no break */    case 4:        if (ndigits <= 0)            ndigits = 1;        ilim = ilim1 = i = ndigits;        break;    case 3:        leftright = 0;        /* no break */    case 5:        i = ndigits + k + 1;        ilim = i;        ilim1 = i - 1;        if (i <= 0)            i = 1;    }    /* ilim is the maximum number of significant digits we want, based on k and ndigits. */    /* ilim1 is the maximum number of significant digits we want, based on k and ndigits,       when it turns out that k was computed too high by one. */    /* Ensure space for at least i+1 characters, including trailing null. */    if (bufsize <= (size_t)i) {        Bfree(b);        JS_ASSERT(JS_FALSE);        return JS_FALSE;    }    s = buf;    if (ilim >= 0 && ilim <= Quick_max && try_quick) {        /* Try to get by with floating-point arithmetic. */        i = 0;        d2 = d;        k0 = k;        ilim0 = ilim;        ieps = 2; /* conservative */        /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */        if (k > 0) {            ds = tens[k&0xf];            j = k >> 4;            if (j & Bletch) {                /* prevent overflows */                j &= Bletch - 1;                d /= bigtens[n_bigtens-1];                ieps++;            }            for(; j; j >>= 1, i++)                if (j & 1) {                    ieps++;                    ds *= bigtens[i];                }            d /= ds;        }        else if ((j1 = -k) != 0) {            d *= tens[j1 & 0xf];            for(j = j1 >> 4; j; j >>= 1, i++)                if (j & 1) {                    ieps++;                    d *= bigtens[i];                }        }        /* Check that k was computed correctly. */        if (k_check && d < 1. && ilim > 0) {            if (ilim1 <= 0)                goto fast_failed;            ilim = ilim1;            k--;            d *= 10.;            ieps++;        }        /* eps bounds the cumulative error. */        eps = ieps*d + 7.;        set_word0(eps, word0(eps) - (P-1)*Exp_msk1);        if (ilim == 0) {            S = mhi = 0;            d -= 5.;            if (d > eps)                goto one_digit;            if (d < -eps)                goto no_digits;            goto fast_failed;        }#ifndef No_leftright        if (leftright) {            /* Use Steele & White method of only             * generating digits needed.             */            eps = 0.5/tens[ilim-1] - eps;            for(i = 0;;) {                L = (Long)d;                d -= L;                *s++ = '0' + (char)L;                if (d < eps)                    goto ret1;                if (1. - d < eps)                    goto bump_up;                if (++i >= ilim)                    break;                eps *= 10.;                d *= 10.;            }        }        else {#endif            /* Generate ilim digits, then fix them up. */            eps *= tens[ilim-1];            for(i = 1;; i++, d *= 10.) {                L = (Long)d;                d -= L;                *s++ = '0' + (char)L;                if (i == ilim) {                    if (d > 0.5 + eps)                        goto bump_up;                    else if (d < 0.5 - eps) {                        while(*--s == '0') ;                        s++;                        goto ret1;                    }                    break;                }            }#ifndef No_leftright        }#endif    fast_failed:        s = buf;        d = d2;        k = k0;        ilim = ilim0;    }    /* Do we have a "small" integer? */    if (be >= 0 && k <= Int_max) {        /* Yes. */        ds = tens[k];        if (ndigits < 0 && ilim <= 0) {            S = mhi = 0;            if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds))                goto no_digits;            goto one_digit;        }        /* Use true number of digits to limit looping. */        for(i = 1; i<=k+1; i++) {            L = (Long) (d / ds);            d -= L*ds;#ifdef Check_FLT_ROUNDS            /* If FLT_ROUNDS == 2, L will usually be high by 1 */            if (d < 0) {    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -