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

📄 dtoa.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
             * special case of mantissa a power of two.             */            if (dsign || word1(rv) || word0(rv) & Bndry_mask#ifdef Avoid_Underflow             || (word0(rv) & Exp_mask) <= (2 * P + 1) * Exp_msk1#else             || (word0(rv) & Exp_mask) <= Exp_msk1#endif                ) {#ifdef SET_INEXACT                if (!delta->x[0] && delta->wds <= 1)                    inexact = 0;#endif                break;            }            if (!delta->x[0] && delta->wds <= 1) {                /* exact result */#ifdef SET_INEXACT                inexact = 0;#endif                break;            }            delta = lshift(delta,Log2P);            if (cmp(delta, bs) > 0)                goto drop_down;            break;        }        if (i == 0) {            /* exactly half-way between */            if (dsign) {                if ((word0(rv) & Bndry_mask1) == Bndry_mask1                 &&  word1(rv) == (#ifdef Avoid_Underflow            (scale && (y = word0(rv) & Exp_mask) <= 2 * P * Exp_msk1)        ? (0xffffffff & (0xffffffff << (2 * P + 1 - (y >> Exp_shift)))) :#endif                           0xffffffff)) {                    /*boundary case -- increment exponent*/                    word0(rv) = (word0(rv) & Exp_mask) + Exp_msk1;                    word1(rv) = 0;#ifdef Avoid_Underflow                    dsign = 0;#endif                    break;                }            } else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {drop_down:                /* boundary case -- decrement exponent */#ifdef Sudden_Underflow /*{{*/                L = word0(rv) & Exp_mask;#ifdef Avoid_Underflow                if (L <= (scale ? (2 * P + 1) * Exp_msk1 : Exp_msk1))#else                if (L <= Exp_msk1)#endif /*Avoid_Underflow*/                    goto undfl;                L -= Exp_msk1;#else /*Sudden_Underflow}{*/#ifdef Avoid_Underflow                if (scale) {                    L = word0(rv) & Exp_mask;                    if (L <= (2 * P + 1) * Exp_msk1) {                        if (L > (P + 2) * Exp_msk1)                            /* round even ==> */                            /* accept rv */                            break;                        /* rv = smallest denormal */                        goto undfl;                    }                }#endif /*Avoid_Underflow*/                L = (word0(rv) & Exp_mask) - Exp_msk1;#endif /*Sudden_Underflow}}*/                word0(rv) = L | Bndry_mask1;                word1(rv) = 0xffffffff;                break;            }            if (!(word1(rv) & LSB))                break;            if (dsign)                dval(rv) += ulp(dval(rv));            else {                dval(rv) -= ulp(dval(rv));#ifndef Sudden_Underflow                if (!dval(rv))                    goto undfl;#endif            }#ifdef Avoid_Underflow            dsign = 1 - dsign;#endif            break;        }        if ((aadj = ratio(delta, bs)) <= 2.) {            if (dsign)                aadj = aadj1 = 1.;            else if (word1(rv) || word0(rv) & Bndry_mask) {#ifndef Sudden_Underflow                if (word1(rv) == Tiny1 && !word0(rv))                    goto undfl;#endif                aadj = 1.;                aadj1 = -1.;            } else {                /* special case -- power of FLT_RADIX to be */                /* rounded down... */                if (aadj < 2. / FLT_RADIX)                    aadj = 1. / FLT_RADIX;                else                    aadj *= 0.5;                aadj1 = -aadj;            }        } else {            aadj *= 0.5;            aadj1 = dsign ? aadj : -aadj;#ifdef Check_FLT_ROUNDS            switch (Rounding) {                case 2: /* towards +infinity */                    aadj1 -= 0.5;                    break;                case 0: /* towards 0 */                case 3: /* towards -infinity */                    aadj1 += 0.5;            }#else            if (Flt_Rounds == 0)                aadj1 += 0.5;#endif /*Check_FLT_ROUNDS*/        }        y = word0(rv) & Exp_mask;        /* Check for overflow */        if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) {            dval(rv0) = dval(rv);            word0(rv) -= P * Exp_msk1;            adj = aadj1 * ulp(dval(rv));            dval(rv) += adj;            if ((word0(rv) & Exp_mask) >= Exp_msk1 * (DBL_MAX_EXP + Bias - P)) {                if (word0(rv0) == Big0 && word1(rv0) == Big1)                    goto ovfl;                word0(rv) = Big0;                word1(rv) = Big1;                goto cont;            } else                word0(rv) += P * Exp_msk1;        } else {#ifdef Avoid_Underflow            if (scale && y <= 2 * P * Exp_msk1) {                if (aadj <= 0x7fffffff) {                    if ((z = (uint32_t)aadj) <= 0)                        z = 1;                    aadj = z;                    aadj1 = dsign ? aadj : -aadj;                }                word0(aadj1) += (2 * P + 1) * Exp_msk1 - y;            }            adj = aadj1 * ulp(dval(rv));            dval(rv) += adj;#else#ifdef Sudden_Underflow            if ((word0(rv) & Exp_mask) <= P * Exp_msk1) {                dval(rv0) = dval(rv);                word0(rv) += P * Exp_msk1;                adj = aadj1 * ulp(dval(rv));                dval(rv) += adj;                if ((word0(rv) & Exp_mask) <= P * Exp_msk1)                {                    if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1)                        goto undfl;                    word0(rv) = Tiny0;                    word1(rv) = Tiny1;                    goto cont;                }                else                    word0(rv) -= P * Exp_msk1;            } else {                adj = aadj1 * ulp(dval(rv));                dval(rv) += adj;            }#else /*Sudden_Underflow*/            /* Compute adj so that the IEEE rounding rules will             * correctly round rv + adj in some half-way cases.             * If rv * ulp(rv) is denormalized (i.e.,             * y <= (P - 1) * Exp_msk1), we must adjust aadj to avoid             * trouble from bits lost to denormalization;             * example: 1.2e-307 .             */            if (y <= (P - 1) * Exp_msk1 && aadj > 1.) {                aadj1 = (double)(int)(aadj + 0.5);                if (!dsign)                    aadj1 = -aadj1;            }            adj = aadj1 * ulp(dval(rv));            dval(rv) += adj;#endif /*Sudden_Underflow*/#endif /*Avoid_Underflow*/        }        z = word0(rv) & Exp_mask;#ifndef SET_INEXACT#ifdef Avoid_Underflow        if (!scale)#endif        if (y == z) {            /* Can we stop now? */            L = (int32_t)aadj;            aadj -= L;            /* The tolerances below are conservative. */            if (dsign || word1(rv) || word0(rv) & Bndry_mask) {                if (aadj < .4999999 || aadj > .5000001)                    break;            } else if (aadj < .4999999 / FLT_RADIX)                break;        }#endifcont:        Bfree(bb);        Bfree(bd);        Bfree(bs);        Bfree(delta);    }#ifdef SET_INEXACT    if (inexact) {        if (!oldinexact) {            word0(rv0) = Exp_1 + (70 << Exp_shift);            word1(rv0) = 0;            dval(rv0) += 1.;        }    } else if (!oldinexact)        clear_inexact();#endif#ifdef Avoid_Underflow    if (scale) {        word0(rv0) = Exp_1 - 2 * P * Exp_msk1;        word1(rv0) = 0;        dval(rv) *= dval(rv0);#ifndef NO_ERRNO        /* try to avoid the bug of testing an 8087 register value */        if (word0(rv) == 0 && word1(rv) == 0)            errno = ERANGE;#endif    }#endif /* Avoid_Underflow */#ifdef SET_INEXACT    if (inexact && !(word0(rv) & Exp_mask)) {        /* set underflow bit */        dval(rv0) = 1e-300;        dval(rv0) *= dval(rv0);    }#endifretfree:    Bfree(bb);    Bfree(bd);    Bfree(bs);    Bfree(bd0);    Bfree(delta);ret:    if (se)        *se = const_cast<char*>(s);    return sign ? -dval(rv) : dval(rv);}static int quorem(Bigint* b, Bigint* S){    int n;    uint32_t *bx, *bxe, q, *sx, *sxe;#ifdef USE_LONG_LONG    unsigned long long borrow, carry, y, ys;#else    uint32_t borrow, carry, y, ys;#ifdef Pack_32    uint32_t si, z, zs;#endif#endif    n = S->wds;    ASSERT_WITH_MESSAGE(b->wds <= n, "oversize b in quorem");    if (b->wds < n)        return 0;    sx = S->x;    sxe = sx + --n;    bx = b->x;    bxe = bx + n;    q = *bxe / (*sxe + 1);    /* ensure q <= true quotient */    ASSERT_WITH_MESSAGE(q <= 9, "oversized quotient in quorem");    if (q) {        borrow = 0;        carry = 0;        do {#ifdef USE_LONG_LONG            ys = *sx++ * (unsigned long long)q + carry;            carry = ys >> 32;            y = *bx - (ys & 0xffffffffUL) - borrow;            borrow = y >> 32 & (uint32_t)1;            *bx++ = (uint32_t)y & 0xffffffffUL;#else#ifdef Pack_32            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);#else            ys = *sx++ * q + carry;            carry = ys >> 16;            y = *bx - (ys & 0xffff) - borrow;            borrow = (y & 0x10000) >> 16;            *bx++ = y & 0xffff;#endif#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 USE_LONG_LONG            ys = *sx++ + carry;            carry = ys >> 32;            y = *bx - (ys & 0xffffffffUL) - borrow;            borrow = y >> 32 & (uint32_t)1;            *bx++ = (uint32_t)y & 0xffffffffUL;#else#ifdef Pack_32            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);#else            ys = *sx++ + carry;            carry = ys >> 16;            y = *bx - (ys & 0xffff) - borrow;            borrow = (y & 0x10000) >> 16;            *bx++ = y & 0xffff;#endif#endif        } while (sx <= sxe);        bx = b->x;        bxe = bx + n;        if (!*bxe) {            while (--bxe > bx && !*bxe)                --n;            b->wds = n;        }    }    return q;}#if !ENABLE(JSC_MULTIPLE_THREADS)static char* dtoa_result;#endifstatic char* rv_alloc(int i){    int k;    int j = sizeof(uint32_t);    for (k = 0;        sizeof(Bigint) - sizeof(uint32_t) - sizeof(int) + j <= (unsigned)i;        j <<= 1)            k++;    int* r = (int*)Balloc(k);    *r = k;    return#if !ENABLE(JSC_MULTIPLE_THREADS)    dtoa_result =#endif        (char*)(r + 1);}static char* nrv_alloc(const char* s, char** rve, int n){    char* rv = rv_alloc(n);    char* t = rv;    while ((*t = *s++))        t++;    if (rve)        *rve = t;    return rv;}/* freedtoa(s) must be used to free values s returned by dtoa * when MULTIPLE_THREADS is #defined.  It should be used in all cases, * but for consistency with earlier versions of dtoa, it is optional * when MULTIPLE_THREADS is not defined. */void freedtoa(char* s){    Bigint* b = (Bigint*)((int*)s - 1);    b->maxwds = 1 << (b->k = *(int*)b);    Bfree(b);#if !ENABLE(JSC_MULTIPLE_THREADS)    if (s == dtoa_result)        dtoa_result = 0;#endif}/* 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 int32_t *       calculation. */char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve){    /*        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.    */    int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0,        j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,        spec_case, try_quick;    int32_t L;#ifndef Sudden_Underflow    int denorm;    uint32_t x;#endif    Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S;    double d2, ds, eps;    char *s, *s0;#ifdef SET_INEXACT    int inexact, oldinexact;#endif#if !ENABLE(JSC_MULTIPLE_THREADS)    if (dtoa_result) {        freedtoa(dtoa_result);        dtoa_result = 0;    }#endif    if (word0(d) & Sign_bit) {        /* set sign for everything, including 0's and NaNs */        *sign = 1;

⌨️ 快捷键说明

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