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

📄 vfnprintf.cxx

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 CXX
📖 第 1 页 / 共 3 页
字号:
                    /* leading zeroes from decimal precision */
                    PAD(dprec - fieldsz, zeroes);
                    ret += dprec - fieldsz;
                }

                /* the string or number proper */
                PRINT(cp, size);
                ret += size;

#ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT
                /* trailing f.p. zeroes */
                PAD(fpprec, zeroes);
                ret += fpprec;
#endif

                /* left-adjusting padding (always blank) */
                if (flags & LADJUST) {
                    if (width - realsz > 0) {
                        PAD(width - realsz, blanks);
                        ret += width - realsz;
                    }
                }

        }
done:
error:
        return (((Cyg_StdioStream *) stream)->get_error() ? EOF : ret);
        /* NOTREACHED */
}


#ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT

static char *
round(double fract, int *exp, char *start, char *end, char ch, char *signp)
{
        double tmp;

        if (fract)
        (void)modf(fract * 10, &tmp);
        else
                tmp = to_digit(ch);
        if (tmp > 4)
                for (;; --end) {
                        if (*end == '.')
                                --end;
                        if (++*end <= '9')
                                break;
                        *end = '0';
                        if (end == start) {
                                if (exp) {      /* e/E; increment exponent */
                                        *end = '1';
                                        ++*exp;
                                }
                                else {          /* f; add extra digit */
                                *--end = '1';
                                --start;
                                }
                                break;
                        }
                }
        /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
        else if (*signp == '-')
                for (;; --end) {
                        if (*end == '.')
                                --end;
                        if (*end != '0')
                                break;
                        if (end == start)
                                *signp = 0;
                }
        return (start);
} // round()


static char *
exponent(char *p, int exp, int fmtch)
{
        char *t;
        char expbuf[MAXEXP];

        *p++ = fmtch;
        if (exp < 0) {
                exp = -exp;
                *p++ = '-';
        }
        else
                *p++ = '+';
        t = expbuf + MAXEXP;
        if (exp > 9) {
                do {
                        *--t = to_char(exp % 10);
                } while ((exp /= 10) > 9);
                *--t = to_char(exp);
                for (; t < expbuf + MAXEXP; *p++ = *t++);
        }
        else {
                *p++ = '0';
                *p++ = to_char(exp);
        }
        return (p);
} // exponent()


static int
cvt(double number, int prec, int flags, char *signp, int fmtch, char *startp,
    char *endp)
{
    Cyg_libm_ieee_double_shape_type ieeefp;
    char *t = startp;

    ieeefp.value = number;
    *signp = 0;
    if ( ieeefp.number.sign ){  // this checks for <0.0 and -0.0
        number = -number;
        *signp = '-';
    }

    if (finite(number)) {
        char *p;
        double fract;
        int dotrim, expcnt, gformat;
        double integer, tmp;

        dotrim = expcnt = gformat = 0;
        fract = modf(number, &integer);

        /* get an extra slot for rounding. */
        t = ++startp;

        /*
         * get integer portion of number; put into the end of the buffer; the
         * .01 is added for modf(356.0 / 10, &integer) returning .59999999...
         */
        for (p = endp - 1; integer; ++expcnt) {
                tmp = modf(integer / 10, &integer);
                *p-- = to_char((int)((tmp + .01) * 10));
        }
        switch (fmtch) {
        case 'f':
                /* reverse integer into beginning of buffer */
                if (expcnt)
                        for (; ++p < endp; *t++ = *p);
                else
                        *t++ = '0';
                /*
                 * if precision required or alternate flag set, add in a
                 * decimal point.
                 */
                if (prec || flags&ALT)
                        *t++ = '.';
                /* if requires more precision and some fraction left */
                if (fract) {
                        if (prec)
                                do {
                                        fract = modf(fract * 10, &tmp);
                                        *t++ = to_char((int)tmp);
                                } while (--prec && fract);
                        if (fract)
                                startp = round(fract, (int *)NULL, startp,
                                    t - 1, (char)0, signp);
                }
                for (; prec--; *t++ = '0');
                break;
        case 'e':
        case 'E':
eformat:        if (expcnt) {
                        *t++ = *++p;
                        if (prec || flags&ALT)
                                *t++ = '.';
                        /* if requires more precision and some integer left */
                        for (; prec && ++p < endp; --prec)
                                *t++ = *p;
                        /*
                         * if done precision and more of the integer component,
                         * round using it; adjust fract so we don't re-round
                         * later.
                         */
                        if (!prec && ++p < endp) {
                                fract = 0;
                                startp = round((double)0, &expcnt, startp,
                                    t - 1, *p, signp);
                        }
                        /* adjust expcnt for digit in front of decimal */
                        --expcnt;
                }
                /* until first fractional digit, decrement exponent */
                else if (fract) {
                        /* adjust expcnt for digit in front of decimal */
                        for (expcnt = -1;; --expcnt) {
                                fract = modf(fract * 10, &tmp);
                                if (tmp)
                                        break;
                        }
                        *t++ = to_char((int)tmp);
                        if (prec || flags&ALT)
                                *t++ = '.';
                }
                else {
                        *t++ = '0';
                        if (prec || flags&ALT)
                                *t++ = '.';
                }
                /* if requires more precision and some fraction left */
                if (fract) {
                        if (prec)
                                do {
                                        fract = modf(fract * 10, &tmp);
                                        *t++ = to_char((int)tmp);
                                } while (--prec && fract);
                        if (fract)
                                startp = round(fract, &expcnt, startp,
                                    t - 1, (char)0, signp);
                }
                /* if requires more precision */
                for (; prec--; *t++ = '0');

                /* unless alternate flag, trim any g/G format trailing 0's */
                if (gformat && !(flags&ALT)) {
                        while (t > startp && *--t == '0');
                        if (*t == '.')
                                --t;
                        ++t;
                }
                t = exponent(t, expcnt, fmtch);
                break;
        case 'g':
        case 'G':
                /* a precision of 0 is treated as a precision of 1. */
                if (!prec)
                        ++prec;
                /*
                 * ``The style used depends on the value converted; style e
                 * will be used only if the exponent resulting from the
                 * conversion is less than -4 or greater than the precision.''
                 *      -- ANSI X3J11
                 */
                if (expcnt > prec || (!expcnt && fract && fract < .0001)) {
                        /*
                         * g/G format counts "significant digits, not digits of
                         * precision; for the e/E format, this just causes an
                         * off-by-one problem, i.e. g/G considers the digit
                         * before the decimal point significant and e/E doesn't
                         * count it as precision.
                         */
                        --prec;
                        fmtch -= 2;             /* G->E, g->e */
                        gformat = 1;
                        goto eformat;
                }
                /*
                 * reverse integer into beginning of buffer,
                 * note, decrement precision
                 */
                if (expcnt)
                        for (; ++p < endp; *t++ = *p, --prec);
                else
                        *t++ = '0';
                /*
                 * if precision required or alternate flag set, add in a
                 * decimal point.  If no digits yet, add in leading 0.
                 */
                if (prec || flags&ALT) {
                        dotrim = 1;
                        *t++ = '.';
                }
                else
                        dotrim = 0;
                /* if requires more precision and some fraction left */
                if (fract) {
                        if (prec) {
                                do {
                                        fract = modf(fract * 10, &tmp);
                                        *t++ = to_char((int)tmp);
                                } while(!tmp);
                                while (--prec && fract) {
                                        fract = modf(fract * 10, &tmp);
                                        *t++ = to_char((int)tmp);
                                }
                        }
                        if (fract)
                                startp = round(fract, (int *)NULL, startp,
                                    t - 1, (char)0, signp);
                }
                /* alternate format, adds 0's for precision, else trim 0's */
                if (flags&ALT)
                        for (; prec--; *t++ = '0');
                else if (dotrim) {
                        while (t > startp && *--t == '0');
                        if (*t != '.')
                                ++t;
                }
        }
    } else {
	unsigned case_adj;
	switch (fmtch) {
	case 'f':
	case 'g':
	case 'e':
	    case_adj = 'a' - 'A';
	    break;
	default:
	    case_adj = 0;
	}
	if (isnan(number)) {
	    *t++ = 'N' + case_adj;
	    *t++ = 'A' + case_adj;
	    *t++ = 'N' + case_adj;
	} else { // infinite
	    *t++ = 'I' + case_adj;
	    *t++ = 'N' + case_adj;
	    *t++ = 'F' + case_adj;
	}
    }
    return (t - startp);
} // cvt()

#endif // ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT

// EOF vfnprintf.cxx

⌨️ 快捷键说明

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