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

📄 dtoa.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        word0(d) &= ~Sign_bit;    /* clear sign bit */    } else        *sign = 0;    if ((word0(d) & Exp_mask) == Exp_mask)    {        /* Infinity or NaN */        *decpt = 9999;        if (!word1(d) && !(word0(d) & 0xfffff))            return nrv_alloc("Infinity", rve, 8);        return nrv_alloc("NaN", rve, 3);    }    if (!dval(d)) {        *decpt = 1;        return nrv_alloc("0", rve, 1);    }#ifdef SET_INEXACT    try_quick = oldinexact = get_inexact();    inexact = 1;#endif    b = d2b(dval(d), &be, &bbits);#ifdef Sudden_Underflow    i = (int)(word0(d) >> Exp_shift1 & (Exp_mask >> Exp_shift1));#else    if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))) {#endif        dval(d2) = dval(d);        word0(d2) &= Frac_mask1;        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;        dval(d2) = x;        word0(d2) -= 31 * Exp_msk1; /* adjust exponent */        i -= (Bias + (P - 1) - 1) + 1;        denorm = 1;    }#endif    ds = (dval(d2) - 1.5) * 0.289529654602168 + 0.1760912590558 + (i * 0.301029995663981);    k = (int)ds;    if (ds < 0. && ds != k)        k--;    /* want k = floor(ds) */    k_check = 1;    if (k >= 0 && k <= Ten_pmax) {        if (dval(d) < tens[k])            k--;        k_check = 0;    }    j = bbits - i - 1;    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;    }#ifndef SET_INEXACT#ifdef Check_FLT_ROUNDS    try_quick = Rounding == 1;#else    try_quick = 1;#endif#endif /*SET_INEXACT*/    leftright = 1;    ilim = ilim1 = -1;    i = 18;    ndigits = 0;    s = s0 = rv_alloc(i);    if (ilim >= 0 && ilim <= Quick_max && try_quick) {        /* Try to get by with floating-point arithmetic. */        i = 0;        dval(d2) = dval(d);        k0 = k;        ilim0 = ilim;        ieps = 2; /* conservative */        if (k > 0) {            ds = tens[k & 0xf];            j = k >> 4;            if (j & Bletch) {                /* prevent overflows */                j &= Bletch - 1;                dval(d) /= bigtens[n_bigtens - 1];                ieps++;            }            for (; j; j >>= 1, i++) {                if (j & 1) {                    ieps++;                    ds *= bigtens[i];                }            }            dval(d) /= ds;        } else if ((j1 = -k)) {            dval(d) *= tens[j1 & 0xf];            for (j = j1 >> 4; j; j >>= 1, i++) {                if (j & 1) {                    ieps++;                    dval(d) *= bigtens[i];                }            }        }        if (k_check && dval(d) < 1. && ilim > 0) {            if (ilim1 <= 0)                goto fast_failed;            ilim = ilim1;            k--;            dval(d) *= 10.;            ieps++;        }        dval(eps) = (ieps * dval(d)) + 7.;        word0(eps) -= (P - 1) * Exp_msk1;        if (ilim == 0) {            S = mhi = 0;            dval(d) -= 5.;            if (dval(d) > dval(eps))                goto one_digit;            if (dval(d) < -dval(eps))                goto no_digits;            goto fast_failed;        }#ifndef No_leftright        if (leftright) {            /* Use Steele & White method of only             * generating digits needed.             */            dval(eps) = (0.5 / tens[ilim - 1]) - dval(eps);            for (i = 0;;) {                L = (long int)dval(d);                dval(d) -= L;                *s++ = '0' + (int)L;                if (dval(d) < dval(eps))                    goto ret1;                if (1. - dval(d) < dval(eps))                    goto bump_up;                if (++i >= ilim)                    break;                dval(eps) *= 10.;                dval(d) *= 10.;            }        } else {#endif            /* Generate ilim digits, then fix them up. */            dval(eps) *= tens[ilim - 1];            for (i = 1;; i++, dval(d) *= 10.) {                L = (int32_t)(dval(d));                if (!(dval(d) -= L))                    ilim = i;                *s++ = '0' + (int)L;                if (i == ilim) {                    if (dval(d) > 0.5 + dval(eps))                        goto bump_up;                    else if (dval(d) < 0.5 - dval(eps)) {                        while (*--s == '0') { }                        s++;                        goto ret1;                    }                    break;                }            }#ifndef No_leftright        }#endiffast_failed:        s = s0;        dval(d) = dval(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 || dval(d) <= 5 * ds)                goto no_digits;            goto one_digit;        }        for (i = 1;; i++, dval(d) *= 10.) {            L = (int32_t)(dval(d) / ds);            dval(d) -= L * ds;#ifdef Check_FLT_ROUNDS            /* If FLT_ROUNDS == 2, L will usually be high by 1 */            if (dval(d) < 0) {                L--;                dval(d) += ds;            }#endif            *s++ = '0' + (int)L;            if (!dval(d)) {#ifdef SET_INEXACT                inexact = 0;#endif                break;            }            if (i == ilim) {                dval(d) += dval(d);                if (dval(d) > ds || dval(d) == ds && L & 1) {bump_up:                    while (*--s == '9')                        if (s == s0) {                            k++;                            *s = '0';                            break;                        }                    ++*s++;                }                break;            }        }        goto ret1;    }    m2 = b2;    m5 = b5;    mhi = mlo = 0;    if (leftright) {        i =#ifndef Sudden_Underflow            denorm ? be + (Bias + (P - 1) - 1 + 1) :#endif            1 + P - bbits;        b2 += i;        s2 += i;        mhi = i2b(1);    }    if (m2 > 0 && s2 > 0) {        i = m2 < s2 ? m2 : s2;        b2 -= i;        m2 -= i;        s2 -= i;    }    if (b5 > 0) {        if (leftright) {            if (m5 > 0) {                mhi = pow5mult(mhi, m5);                b1 = mult(mhi, b);                Bfree(b);                b = b1;            }            if ((j = b5 - m5))                b = pow5mult(b, j);        } else            b = pow5mult(b, b5);        }    S = i2b(1);    if (s5 > 0)        S = pow5mult(S, s5);    /* Check for special case that d is a normalized power of 2. */    spec_case = 0;    if (!word1(d) && !(word0(d) & Bndry_mask)#ifndef Sudden_Underflow     && word0(d) & (Exp_mask & ~Exp_msk1)#endif            ) {        /* The special case */        b2 += Log2P;        s2 += Log2P;        spec_case = 1;    }    /* Arrange for convenient computation of quotients:     * shift left if necessary so divisor has 4 leading 0 bits.     *     * Perhaps we should just compute leading 28 bits of S once     * and for all and pass them and a shift to quorem, so it     * can do shifts and ors to compute the numerator for q.     */#ifdef Pack_32    if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds - 1]) : 1) + s2) & 0x1f))        i = 32 - i;#else    if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds - 1]) : 1) + s2) & 0xf))        i = 16 - i;#endif    if (i > 4) {        i -= 4;        b2 += i;        m2 += i;        s2 += i;    } else if (i < 4) {        i += 28;        b2 += i;        m2 += i;        s2 += i;    }    if (b2 > 0)        b = lshift(b, b2);    if (s2 > 0)        S = lshift(S, s2);    if (k_check) {        if (cmp(b,S) < 0) {            k--;            b = multadd(b, 10, 0);    /* we botched the k estimate */            if (leftright)                mhi = multadd(mhi, 10, 0);            ilim = ilim1;        }    }    if (leftright) {        if (m2 > 0)            mhi = lshift(mhi, m2);        /* Compute mlo -- check for special case         * that d is a normalized power of 2.         */        mlo = mhi;        if (spec_case) {            mhi = Balloc(mhi->k);            Bcopy(mhi, mlo);            mhi = lshift(mhi, Log2P);        }        for (i = 1;;i++) {            dig = quorem(b,S) + '0';            /* Do we yet have the shortest decimal string             * that will round to d?             */            j = cmp(b, mlo);            delta = diff(S, mhi);            j1 = delta->sign ? 1 : cmp(b, delta);            Bfree(delta);            if (j1 == 0 && !(word1(d) & 1)) {                if (dig == '9')                    goto round_9_up;                if (j > 0)                    dig++;#ifdef SET_INEXACT                else if (!b->x[0] && b->wds <= 1)                    inexact = 0;#endif                *s++ = dig;                goto ret;            }            if (j < 0 || j == 0 && !(word1(d) & 1)) {                if (!b->x[0] && b->wds <= 1) {#ifdef SET_INEXACT                    inexact = 0;#endif                    goto accept_dig;                }                if (j1 > 0) {                    b = lshift(b, 1);                    j1 = cmp(b, S);                    if ((j1 > 0 || j1 == 0 && dig & 1) && dig++ == '9')                        goto round_9_up;                }accept_dig:                *s++ = dig;                goto ret;            }            if (j1 > 0) {                if (dig == '9') { /* possible if i == 1 */round_9_up:                    *s++ = '9';                    goto roundoff;                }                *s++ = dig + 1;                goto ret;            }            *s++ = dig;            if (i == ilim)                break;            b = multadd(b, 10, 0);            if (mlo == mhi)                mlo = mhi = multadd(mhi, 10, 0);            else {                mlo = multadd(mlo, 10, 0);                mhi = multadd(mhi, 10, 0);            }        }    } else        for (i = 1;; i++) {            *s++ = dig = quorem(b,S) + '0';            if (!b->x[0] && b->wds <= 1) {#ifdef SET_INEXACT                inexact = 0;#endif                goto ret;            }            if (i >= ilim)                break;            b = multadd(b, 10, 0);        }    /* Round off last digit */    b = lshift(b, 1);    j = cmp(b, S);    if (j > 0 || j == 0 && dig & 1) {roundoff:        while (*--s == '9')            if (s == s0) {                k++;                *s++ = '1';                goto ret;            }        ++*s++;    } else {        while (*--s == '0') { }        s++;    }    goto ret;no_digits:    k = -1 - ndigits;    goto ret;one_digit:    *s++ = '1';    k++;    goto ret;ret:    Bfree(S);    if (mhi) {        if (mlo && mlo != mhi)            Bfree(mlo);        Bfree(mhi);    }ret1:#ifdef SET_INEXACT    if (inexact) {        if (!oldinexact) {            word0(d) = Exp_1 + (70 << Exp_shift);            word1(d) = 0;            dval(d) += 1.;        }    } else if (!oldinexact)        clear_inexact();#endif    Bfree(b);    *s = 0;    *decpt = k + 1;    if (rve)        *rve = s;    return s0;}} // namespace WTF

⌨️ 快捷键说明

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