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

📄 dtoa.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#endif    if (k > 0)        word0(da) += k * Exp_msk1;    else {        k = -k;        word0(db) += k * Exp_msk1;    }    return dval(da) / dval(db);}static const double tens[] = {        1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,        1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,        1e20, 1e21, 1e22};static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,#ifdef Avoid_Underflow        9007199254740992. * 9007199254740992.e-256        /* = 2^106 * 1e-53 */#else        1e-256#endif};/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow *//* flag unnecessarily.  It leads to a song and dance at the end of strtod. */#define Scale_Bit 0x10#define n_bigtens 5#if defined(INFNAN_CHECK)#ifndef NAN_WORD0#define NAN_WORD0 0x7ff80000#endif#ifndef NAN_WORD1#define NAN_WORD1 0#endifstatic int match(const char** sp, const char* t){    int c, d;    const char* s = *sp;    while ((d = *t++)) {        if ((c = *++s) >= 'A' && c <= 'Z')            c += 'a' - 'A';        if (c != d)            return 0;    }    *sp = s + 1;    return 1;}#ifndef No_Hex_NaNstatic void hexnan(double* rvp, const char** sp){    uint32_t c, x[2];    const char* s;    int havedig, udx0, xshift;    x[0] = x[1] = 0;    havedig = xshift = 0;    udx0 = 1;    s = *sp;    while ((c = *(const unsigned char*)++s)) {        if (c >= '0' && c <= '9')            c -= '0';        else if (c >= 'a' && c <= 'f')            c += 10 - 'a';        else if (c >= 'A' && c <= 'F')            c += 10 - 'A';        else if (c <= ' ') {            if (udx0 && havedig) {                udx0 = 0;                xshift = 1;            }            continue;        } else if (/*(*/ c == ')' && havedig) {            *sp = s + 1;            break;        } else            return;    /* invalid form: don't change *sp */        havedig = 1;        if (xshift) {            xshift = 0;            x[0] = x[1];            x[1] = 0;        }        if (udx0)            x[0] = (x[0] << 4) | (x[1] >> 28);        x[1] = (x[1] << 4) | c;    }    if ((x[0] &= 0xfffff) || x[1]) {        word0(*rvp) = Exp_mask | x[0];        word1(*rvp) = x[1];    }}#endif /*No_Hex_NaN*/#endif /* INFNAN_CHECK */double strtod(const char* s00, char** se){#ifdef Avoid_Underflow    int scale;#endif    int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,         e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;    const char *s, *s0, *s1;    double aadj, aadj1, adj, rv, rv0;    int32_t L;    uint32_t y, z;    Bigint *bb = NULL, *bb1 = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL;#ifdef SET_INEXACT    int inexact, oldinexact;#endif    sign = nz0 = nz = 0;    dval(rv) = 0.;    for (s = s00; ; s++)        switch (*s) {            case '-':                sign = 1;                /* no break */            case '+':                if (*++s)                    goto break2;                /* no break */            case 0:                goto ret0;            case '\t':            case '\n':            case '\v':            case '\f':            case '\r':            case ' ':                continue;            default:                goto break2;        }break2:    if (*s == '0') {        nz0 = 1;        while (*++s == '0') { }        if (!*s)            goto ret;    }    s0 = s;    y = z = 0;    for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)        if (nd < 9)            y = (10 * y) + c - '0';        else if (nd < 16)            z = (10 * z) + c - '0';    nd0 = nd;    if (c == '.') {        c = *++s;        if (!nd) {            for (; c == '0'; c = *++s)                nz++;            if (c > '0' && c <= '9') {                s0 = s;                nf += nz;                nz = 0;                goto have_dig;            }            goto dig_done;        }        for (; c >= '0' && c <= '9'; c = *++s) {have_dig:            nz++;            if (c -= '0') {                nf += nz;                for (i = 1; i < nz; i++)                    if (nd++ < 9)                        y *= 10;                    else if (nd <= DBL_DIG + 1)                        z *= 10;                if (nd++ < 9)                    y = (10 * y) + c;                else if (nd <= DBL_DIG + 1)                    z = (10 * z) + c;                nz = 0;            }        }    }dig_done:    e = 0;    if (c == 'e' || c == 'E') {        if (!nd && !nz && !nz0) {            goto ret0;        }        s00 = s;        esign = 0;        switch (c = *++s) {            case '-':                esign = 1;            case '+':                c = *++s;        }        if (c >= '0' && c <= '9') {            while (c == '0')                c = *++s;            if (c > '0' && c <= '9') {                L = c - '0';                s1 = s;                while ((c = *++s) >= '0' && c <= '9')                    L = (10 * L) + c - '0';                if (s - s1 > 8 || L > 19999)                    /* Avoid confusion from exponents                     * so large that e might overflow.                     */                    e = 19999; /* safe for 16 bit ints */                else                    e = (int)L;                if (esign)                    e = -e;            } else                e = 0;        } else            s = s00;    }    if (!nd) {        if (!nz && !nz0) {#ifdef INFNAN_CHECK            /* Check for Nan and Infinity */            switch(c) {                case 'i':                case 'I':                    if (match(&s,"nf")) {                        --s;                        if (!match(&s,"inity"))                            ++s;                        word0(rv) = 0x7ff00000;                        word1(rv) = 0;                        goto ret;                    }                    break;                case 'n':                case 'N':                    if (match(&s, "an")) {                        word0(rv) = NAN_WORD0;                        word1(rv) = NAN_WORD1;#ifndef No_Hex_NaN                        if (*s == '(') /*)*/                            hexnan(&rv, &s);#endif                        goto ret;                    }            }#endif /* INFNAN_CHECK */ret0:            s = s00;            sign = 0;        }        goto ret;    }    e1 = e -= nf;    /* Now we have nd0 digits, starting at s0, followed by a     * decimal point, followed by nd-nd0 digits.  The number we're     * after is the integer represented by those digits times     * 10**e */    if (!nd0)        nd0 = nd;    k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;    dval(rv) = y;    if (k > 9) {#ifdef SET_INEXACT        if (k > DBL_DIG)            oldinexact = get_inexact();#endif        dval(rv) = tens[k - 9] * dval(rv) + z;    }    bd0 = 0;    if (nd <= DBL_DIG && Flt_Rounds == 1) {        if (!e)            goto ret;        if (e > 0) {            if (e <= Ten_pmax) {                /* rv = */ rounded_product(dval(rv), tens[e]);                goto ret;            }            i = DBL_DIG - nd;            if (e <= Ten_pmax + i) {                /* A fancier test would sometimes let us do                 * this for larger i values.                 */                e -= i;                dval(rv) *= tens[i];                /* rv = */ rounded_product(dval(rv), tens[e]);                goto ret;            }        }#ifndef Inaccurate_Divide        else if (e >= -Ten_pmax) {            /* rv = */ rounded_quotient(dval(rv), tens[-e]);            goto ret;        }#endif    }    e1 += nd - k;#ifdef SET_INEXACT    inexact = 1;    if (k <= DBL_DIG)        oldinexact = get_inexact();#endif#ifdef Avoid_Underflow    scale = 0;#endif    /* Get starting approximation = rv * 10**e1 */    if (e1 > 0) {        if ((i = e1 & 15))            dval(rv) *= tens[i];        if (e1 &= ~15) {            if (e1 > DBL_MAX_10_EXP) {ovfl:#ifndef NO_ERRNO                errno = ERANGE;#endif                /* Can't trust HUGE_VAL */                word0(rv) = Exp_mask;                word1(rv) = 0;#ifdef SET_INEXACT                /* set overflow bit */                dval(rv0) = 1e300;                dval(rv0) *= dval(rv0);#endif                if (bd0)                    goto retfree;                goto ret;            }            e1 >>= 4;            for (j = 0; e1 > 1; j++, e1 >>= 1)                if (e1 & 1)                    dval(rv) *= bigtens[j];        /* The last multiplication could overflow. */            word0(rv) -= P * Exp_msk1;            dval(rv) *= bigtens[j];            if ((z = word0(rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - P))                goto ovfl;            if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) {                /* set to largest number */                /* (Can't trust DBL_MAX) */                word0(rv) = Big0;                word1(rv) = Big1;            } else                word0(rv) += P * Exp_msk1;        }    } else if (e1 < 0) {        e1 = -e1;        if ((i = e1 & 15))            dval(rv) /= tens[i];        if (e1 >>= 4) {            if (e1 >= 1 << n_bigtens)                goto undfl;#ifdef Avoid_Underflow            if (e1 & Scale_Bit)                scale = 2 * P;            for (j = 0; e1 > 0; j++, e1 >>= 1)                if (e1 & 1)                    dval(rv) *= tinytens[j];            if (scale && (j = (2 * P) + 1 - ((word0(rv) & Exp_mask) >> Exp_shift)) > 0) {                /* scaled rv is denormal; zap j low bits */                if (j >= 32) {                    word1(rv) = 0;                    if (j >= 53)                       word0(rv) = (P + 2) * Exp_msk1;                    else                       word0(rv) &= 0xffffffff << j - 32;                } else                    word1(rv) &= 0xffffffff << j;            }#else            for (j = 0; e1 > 1; j++, e1 >>= 1)                if (e1 & 1)                    dval(rv) *= tinytens[j];            /* The last multiplication could underflow. */            dval(rv0) = dval(rv);            dval(rv) *= tinytens[j];            if (!dval(rv)) {                dval(rv) = 2. * dval(rv0);                dval(rv) *= tinytens[j];#endif                if (!dval(rv)) {undfl:                    dval(rv) = 0.;#ifndef NO_ERRNO                    errno = ERANGE;#endif                    if (bd0)                        goto retfree;                    goto ret;                }#ifndef Avoid_Underflow                word0(rv) = Tiny0;                word1(rv) = Tiny1;                /* The refinement below will clean                 * this approximation up.                 */            }#endif        }    }    /* Now the hard part -- adjusting rv to the correct value.*/    /* Put digits into bd: true value = bd * 10^e */    bd0 = s2b(s0, nd0, nd, y);    for (;;) {        bd = Balloc(bd0->k);        Bcopy(bd, bd0);        bb = d2b(dval(rv), &bbe, &bbbits);    /* rv = bb * 2^bbe */        bs = i2b(1);        if (e >= 0) {            bb2 = bb5 = 0;            bd2 = bd5 = e;        } else {            bb2 = bb5 = -e;            bd2 = bd5 = 0;        }        if (bbe >= 0)            bb2 += bbe;        else            bd2 -= bbe;        bs2 = bb2;#ifdef Avoid_Underflow        j = bbe - scale;        i = j + bbbits - 1;    /* logb(rv) */        if (i < Emin)    /* denormal */            j += P - Emin;        else            j = P + 1 - bbbits;#else /*Avoid_Underflow*/#ifdef Sudden_Underflow        j = P + 1 - bbbits;#else /*Sudden_Underflow*/        j = bbe;        i = j + bbbits - 1;    /* logb(rv) */        if (i < Emin)    /* denormal */            j += P - Emin;        else            j = P + 1 - bbbits;#endif /*Sudden_Underflow*/#endif /*Avoid_Underflow*/        bb2 += j;        bd2 += j;#ifdef Avoid_Underflow        bd2 += scale;#endif        i = bb2 < bd2 ? bb2 : bd2;        if (i > bs2)            i = bs2;        if (i > 0) {            bb2 -= i;            bd2 -= i;            bs2 -= i;        }        if (bb5 > 0) {            bs = pow5mult(bs, bb5);            bb1 = mult(bs, bb);            Bfree(bb);            bb = bb1;        }        if (bb2 > 0)            bb = lshift(bb, bb2);        if (bd5 > 0)            bd = pow5mult(bd, bd5);        if (bd2 > 0)            bd = lshift(bd, bd2);        if (bs2 > 0)            bs = lshift(bs, bs2);        delta = diff(bb, bd);        dsign = delta->sign;        delta->sign = 0;        i = cmp(delta, bs);        if (i < 0) {            /* Error is less than half an ulp -- check for

⌨️ 快捷键说明

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