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

📄 floatconv.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
                        si = *sx++;                        ys = (si & 0xffff) + carry;                        zs = (si >> 16) + (ys >> 16);                        carry = zs >> 16;                        y = (*bx & 0xffff) - (ys & 0xffff) + borrow;                        borrow = y >> 16;                        Sign_Extend(borrow, y);                        z = (*bx >> 16) - (zs & 0xffff) + borrow;                        borrow = z >> 16;                        Sign_Extend(borrow, z);                        Storeinc(bx, z, y);                        }                        while(sx <= sxe);                bx = b->x;                bxe = bx + n;                if (!*bxe) {                        while(--bxe > bx && !*bxe)                                --n;                        b->wds = n;                        }                }        return 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. */ char *_IO_dtoa#ifdef KR_headers        (d, mode, ndigits, decpt, sign, rve)        double d; int mode, ndigits, *decpt, *sign; char **rve;#else        (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)#endif{ /*     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.        */        _G_int32_t 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;        _G_int32_t L;#ifndef Sudden_Underflow        int denorm;#endif	Bigint _b_avail, _b, _mhi, _mlo, _S;	Bigint *b_avail = Binit(&_b_avail);	Bigint *b = Binit(&_b);	Bigint *S = Binit(&_S);	/* mhi and mlo are only set and used if leftright. */        Bigint *mhi = NULL, *mlo = NULL;        double d2, ds, eps;        char *s, *s0;        static Bigint *result = NULL;        static int result_k;	TEST_ENDIANNESS;        if (result) {		/* result is contains a string, so its fields (interpreted		   as a Bigint have been trashed.  Restore them.		   This is a really ugly interface - result should		   not be static, since that is not thread-safe.  FIXME. */                result->k = result_k;                result->maxwds = 1 << result_k;                result->on_stack = 0;                }        if (word0(d) & Sign_bit) {                /* set sign for everything, including 0's and NaNs */                *sign = 1;                setword0(d, word0(d) & ~Sign_bit);  /* clear sign bit */                }        else                *sign = 0;#if defined(IEEE_Arith) + defined(VAX)#ifdef IEEE_Arith        if ((word0(d) & Exp_mask) == Exp_mask)#else        if (word0(d)  == 0x8000)#endif                {                /* Infinity or NaN */                *decpt = 9999;#ifdef IEEE_Arith		if (!word1(d) && !(word0(d) & 0xfffff))		  {		    s = "Infinity";		    if (rve)		      *rve = s + 8;		  }		else#endif		  {		    s = "NaN";		    if (rve)		      *rve = s +3;		  }                return s;                }#endif#ifdef IBM        d += 0; /* normalize */#endif        if (!d) {                *decpt = 1;                s = "0";                if (rve)                        *rve = s + 1;                return s;                }        b = d2b(b, d, &be, &bbits);        i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));#ifndef Sudden_Underflow        if (i) {#endif                d2 = d;                setword0(d2, (word0(d2) & Frac_mask1) | Exp_11);#ifdef IBM                if (j = 11 - hi0bits(word0(d2) & Frac_mask))                        d2 /= 1 << j;#endif                i -= Bias;#ifdef IBM                i <<= 2;                i += j;#endif#ifndef Sudden_Underflow                denorm = 0;                }        else {                /* d is denormalized */		unsigned32 x;                i = bbits + be + (Bias + (P-1) - 1);                x = i > 32  ? word0(d) << (64 - i) | word1(d) >> (i - 32)                            : word1(d) << (32 - i);                d2 = x;                addword0(d2, - 31*Exp_msk1); /* adjust exponent */                i -= (Bias + (P-1) - 1) + 1;                denorm = 1;                }#endif	/* Now i is the unbiased base-2 exponent. */        /* 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*log(2)/log(10) + log10(d2)         *         * This suggests computing an approximation k to log10(d) by         *         * k = i*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) by 0.301029995663981; since |i| <= 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.)         */        ds = (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 (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;                }        if (mode < 0 || mode > 9)                mode = 0;        try_quick = 1;        if (mode > 5) {                mode -= 4;                try_quick = 0;                }        leftright = 1;        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;                }	/* i is now an upper bound of the number of digits to generate. */        j = sizeof(unsigned32) * (1<<BIGINT_MINIMUM_K);	/* The test is <= so as to allow room for the final '\0'. */        for(result_k = BIGINT_MINIMUM_K; BIGINT_HEADER_SIZE + j <= i;                j <<= 1) result_k++;        if (!result || result_k > result->k)        {          Bfree (result);          result = Balloc(result_k);        }        s = s0 = (char *)result;        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 */                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)) {                        d *= tens[j1 & 0xf];                        for(j = j1 >> 4; j; j >>= 1, i++)                                if (j & 1) {                                        ieps++;                                        d *= bigtens[i];                                        }                        }                if (k_check && d < 1. && ilim > 0) {                        if (ilim1 <= 0)                                goto fast_failed;                        ilim = ilim1;                        k--;                        d *= 10.;                        ieps++;                        }                eps = ieps*d + 7.;                addword0(eps, - (P-1)*Exp_msk1);                if (ilim == 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 = (_G_int32_t)d;                                d -= L;                                *s++ = '0' + (int)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 = (_G_int32_t)d;                                d -= L;                                *s++ = '0' + (int)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 = s0;                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) {                        if (ilim < 0 || d <= 5*ds)                                goto no_digits;                        goto one_digit;                        }                for(i = 1;; i++) {                        L = (_G_int32_t)(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 + -