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

📄 vfprintf.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
					} while (_ulong);					/* handle octal leading 0 */					if (is_flag(ALT) && *cp != '0')						*--cp = '0';					break;				case DEC:#if	defined(__TCS__)/* * Integer divide and remainder are very inefficient on TM-1, * so we try to avoid them by using custom ops. * Use umulm() to multiply by 2^32/10 (rounded up to 0x1999999A) * and take the high order word of the 64-bit result to get _ulong / 10; * similarly for remainder. * This does not work for very large _ulong because of the rounding, * so we just use normal / and % for those cases (once). */					if (_ulong >= 0x40000000) {						/* Use / and % at most once. */						*--cp = _ulong % 10 + '0';						_ulong /= 10;					}					/* Many numbers are 1 digit. */					while (_ulong >= 10) {						unsigned long udiv10;						udiv10 = umulm(_ulong, 0x1999999A);						*--cp = umulm(10, _ulong * 0x1999999A) + '0';						_ulong = udiv10;					}					*--cp = _ulong + '0';					break;#else	/* defined(__TCS__) */					/* Many numbers are 1 digit. */					while (_ulong >= 10) {						*--cp = _ulong % 10 + '0';						_ulong /= 10;					}					*--cp = _ulong + '0';					break;#endif	/* defined(__TCS__) */				case HEX:					do {						*--cp = xdigs[_ulong & 15];						_ulong >>= 4;					} while (_ulong);					break;				}			}			size = buf + NBUF - cp;		skipsize:			break;		default:	/* "%?" prints ?, unless ? is NUL */			if (ch == '\0')				goto done;			/* pretend it was %c with argument ch */			cp = buf;			*cp = ch;			size = 1;			sign = 0;			break;		}		/*		 * All reasonable formats wind up here.  At this point,		 * `cp' points to a string of length size which (if !LADJUST)		 * should be padded out to `width' places.  If ZEROPAD,		 * it should first be prefixed by any		 * sign or other prefix; otherwise, it should be blank		 * padded before the prefix is emitted.  After any		 * left-hand padding and prefixing, emit zeroes		 * required by a decimal [diouxX] precision, then print		 * the string proper, then emit zeroes required by any		 * leftover floating precision and print the floating exponent;		 * finally, if LADJUST, pad with blanks.		 */		/*		 * compute actual size, so we know how much to pad.		 * fieldsz excludes decimal prec; realsz includes it		 */		fieldsz = size + expsize + fppad;		if (sign) {			if (dprec)				dprec++;			fieldsz++;		} else if (is_flag(HEXPREFIX))			fieldsz += 2;		realsz = dprec > fieldsz ? dprec : fieldsz;		/* right-adjusting blank padding */		if (!is_flag(LADJUST) && !is_flag(ZEROPAD))			PAD(width - realsz, blanks);		/* prefix */		if (sign) {			PRINT(&sign, 1);		} else if (is_flag(HEXPREFIX)) {			ox[0] = '0';			ox[1] = ch;			PRINT(ox, 2);		}		/* right-adjusting zero padding */		if (is_flag(ZEROPAD) && !is_flag(LADJUST))			PAD(width - realsz, zeroes);		/* leading zeroes from decimal precision */		PAD(dprec - fieldsz, zeroes);		/* the string or number proper */		PRINT(cp, size);		/* trailing f.p. zeroes */		PAD(fppad, zeroes);		/* trailing f.p. exponent */		PRINT(expbuf, expsize);		/* left-adjusting padding (always blank) */		if (is_flag(LADJUST))			PAD(width - realsz, blanks);		/* finally, adjust ret */		ret += width > realsz ? width : realsz;		FLUSH();	/* copy out the I/O vectors */	}done:	FLUSH();error:        result= (__sferror(stream)) ? EOF : ret;	EXCL_END(&stream->_file_lock);	return result;}/* * This routine does all the significant formatting for floating point output, * leaving it up to the caller to provide padding and output the result. * Convert double d with given format, precision and flags into buf. * Store the sign through signp, the exponent (if any) in expbuf, * the exponent size (if any) through expsizep, * and the floating point 0-padding required through fppadp. * The 0-padding is extra precision required by the precision field; it is * not part of the returned buffer because prec might be arbitrarily large. * The exponent is not part of the returned buffer because the extra 0-padding * must precede the exponent in the actual output. * Return the number of characters written to buf, not including expsize. * * Exceptions: *	"NaN"		for NaNs *	"+Inf"		for +Infinity *	"-Inf"		for -Infinity *	"-0"		for minus zero * * Note: this currently prints IEEE minus zero * and values which round to -0 with '-' sign, * e.g. ``printf("%.3f", -.0001);'' prints "-0.000". * This may or may not be desirable. * To change this behavior, pass a different signp (not &sign) * in the fpcvt() call from vfprintf(), pass signp down to significand() * so significand() can zap the minus sign if the result rounds to 0, * and resolve the new *signp with sign in vfprintf(). * The separate signp would be needed to avoid zapping * a specified '+' or ' ' flag in vfprintf(). */staticintfpcvt(double d, char *buf, int fmtch, int prec, int flags,      char *signp, char *expbuf, int *expsizep, int *fppadp){	register int digits;	register char *cp, *s, *expp;	int decexp, gformat;	char digbuf[MAXPREC];#if	defined(__IEEE_FP__)	/* Deal with NaN and infinities. */	if (_isNaN(d)) {		strcpy(buf, "NaN");		return 3;	} else if (_isInfinity(d)) {		strcpy(buf, (d > 0) ? "+Inf" : "-Inf");		return 4;	} else if (_ismZero(d)) {		/* print minus zero with '-' */		d = -d;		*signp = '-';	}#endif	/* defined(__IEEE_FP__) */	/* Force d nonnegative. */	if (d < 0) {		*signp = '-';		d = -d;	}	s = buf;				/* destination */	cp = digbuf;				/* source */	gformat = (fmtch == 'g' || fmtch == 'G');	/* Check for default precision. */	if (prec == -1)		prec = DEFPREC;			/* -1 means use default */	else if (prec == 0 && gformat)		prec = 1;			/* because ISO 9899-1990 says so */	/* Find the significant digits in d. */	digits = significand(d, fmtch, prec, digbuf, &decexp);	/* Convert the number to the desired format. */	switch(fmtch) {	case 'e':	case 'E':e_or_g:		/*		 * Store the exponent into expbuf and its length to *expsizep.		 * N.B. the code below assumes decexp < 1000.		 */		expp = expbuf;		*expp++ = fmtch;		/* 'E' or 'e' */		if (decexp < 0) {		/* '+' or '-' */			decexp = -decexp;			*expp++ = '-';		} else			*expp++ = '+';		if (decexp >= 100) {			*expp++ = (decexp / 100) + '0';			decexp %= 100;		}		*expp++ = (decexp / 10) + '0';	/* at least two digits mandated */		decexp %= 10;		*expp++ = decexp + '0';		*expsizep = expp - expbuf;		/* Store the first significand digit and decimal point. */		*s++ = *cp++;			/* digit preceding '.' */		--digits;		if (is_flag(ALT) || (prec > 0 && (!gformat || digits > 0)))			*s++ = '.';		break;	case 'g':	case 'G':		if (decexp < -4 || decexp >= prec) {			/*			 * Use 'e' or 'E' format.			 * 'e' precision means digits after the '.', but			 * 'g' precision means significant digits;			 * hence the "--prec;" below, since there is one			 * significant digit before the '.'.			 */			fmtch -= 2;		/* 'G'->'E', 'g'->'e' */			--prec;			/* adjust precision */			goto e_or_g;		}		/* FALLTHROUGH */		/* use 'f' format. */	case 'f':		if (decexp >= 0) {			for ( ; digits > 0 && decexp >= 0; --digits, --decexp) {				*s++ = *cp++;	/* store digit before '.' */				if (gformat)					--prec;			}			for ( ; decexp >= 0; --decexp) {				*s++ = '0';	/* out of digits, store a significant  0 */				if (gformat)					--prec;			}		} else			*s++ = '0';		/* store insignificant '0' before '.' */		/* Need decimal point if precision remains or alt flag. */		if (is_flag(ALT) || (prec > 0 && (!gformat || digits > 0)))			*s++ = '.';		/* store decimal point */		for ( ; decexp < -1 && prec > 0; ++decexp) {			*s++ = '0';		/* store insignificant '0' after '.' */			if (!gformat)				--prec;		}		break;	}	/* Store the remainder of the significand and pad later as needed. */	for ( ; digits > 0 && prec > 0; --digits, --prec)		*s++ = *cp++;			/* store digits after '.' */	if (prec > 0 && (!gformat || is_flag(ALT)))		*fppadp += prec;		/* pad with more 0s later */	return s - buf;}/* * This routine does the serious work of fp output conversion: * it produces the sequence of significant digits of the result, * not yet formatted. * Given a nonnegative double d and a desired format and precision, * convert d into a nonempty string of decimal digits in the * supplied buffer and store the corresponding decimal exponent in *expp. * Round the result appropriately and return the length of the result string. * The returned string has neither leading nor trailing zeros (or is "0") * and is at most MAXPREC characters long. * It has an implicit decimal point after the first digit. */staticintsignificand(double d, int fmtch, int prec, char *buf, int *expp){	register char *cp;	register int i, digits;	cp = buf;	if (d == 0.0) {			/* just return "0" */zero:		*cp = '0';		*expp = 0;		return 1;	}	/*	 * Find the decimal exponent and reduce d to [1., 10).	 * N.B. *expp may be adjusted below if the result rounds up.	 * We need to know the decimal exponent in order to decide	 * how many significant digits will be required for 'f' format.	 */	d = frexp10(d, expp);	/*	 * Compute the number of significant digits needed, depending on the format.	 * Note that the number of significant digits needed must be positive	 * for 'e' (because prec >= 0 and digits = 1 + prec)	 * and for 'g' (because prec > 0 and digits = prec),	 * but may be zero or negative for 'f' when converting	 * a value with a negative decimal exponent.	 * Digits after MAXPREC significant digits are noise, do not convert them.	 * The last of the MAXPREC digits may be partially noise but	 * we convert it anyway rather than throw away some valid precision.	 */	if (fmtch == 'e' || fmtch == 'E')		digits = 1 + prec;		/* e.g. 1.234 */	else if (fmtch == 'f')		digits = *expp + 1 + prec;	/* e.g. 123.456 */	else		digits = prec;			/* 'g' or 'G' format */	if (digits > MAXPREC)		digits = MAXPREC;		/* convert at most MAXPREC digits */	/* Check for zero digits or negative digits ('f' format). */	if (digits <= 0) {		if (digits == 0 && d >= 5.0) {	/* round up to return "1" */			*cp = '1';			++*expp;		/* adjust decimal exponent */			return 1;		} else			goto zero;		/* return "0" */	}	/* Store result digits. */	while (cp < &buf[digits] && d != 0) {		i = (int)d;		*cp++ = i + '0';		#if 0		_write(1, "[", 1);		_write(1, cp - 1, 1);		_write(1, "]", 1);		#endif		d = 10.0 * (d - (double)i);	/* reduce d for next digit */	}	/* Round the result and strip trailing zeros. */	if (d < 5.0) {				/* do not round up */		while (cp > &buf[1] && *(cp - 1) == '0')			--cp;			/* skip a trailing zero */		return cp - buf;		/* return result length */	} else {				/* round up */		while (--cp >= buf)		/* look at previous digit */			if (++*cp <= '9')	/* bump it */				return cp + 1 - buf;	/* done */		/*		 * cp == &buf[-1], so we rounded e.g. "99" to "00".		 * Adjust the decimal exponent and return "1".		 */		++*expp;			/* bump decimal exponent */		*++cp = '1';			/* return "1" */		return 1;	}	/* NOTREACHED */}/* * frexp10() is like frexp() with a decimal rather than a binary base. * For nonzero d, it returns a double decfrac in the range [+-][1., 10) and * stores a decimal exponent through *expp, so d = decfrac * 10 ^ (*expp). * It extracts the decimal exponent fairly efficiently by using frexp() * and scales d with one multiplication and possibly one division. * Useful equations: * log10(d) = log10(decfrac) + decexp, where log10(decfrac) is in [0., 1.); * log10(d) = log2(d) / log2(10); * d = binfrac * 2 ^ binexp, so log2(d) = log2(binfrac) + binexp. * If binfrac and binexp are the results of frexp(), * then binfrac is in [.5, 1.) and log2(binfrac) is in [-1., 0). * Together these imply that (binexp - 1 / log2(10)) is a good lower bound * for decexp, off by at most 1. * * Exceptions: *	Error	Return	Store	Condition *	none	0.0	0.0	d is 0.0 *	EDOM	NaN	NaN	d is NaN *	ERANGE	[+-]1.0	INT_MAX	d is [+-]Infinity */staticdoublefrexp10(double d, int *expp){	register decexp;	int binexp;	double dexp;#if	0	/*	 * The code here to do NaNs, infinities and 0.0 in not needed,	 * because fpcvt() checks for NaNs and infinities	 * and significand() checks for 0.0 before frexp10() gets called.	 */#if	defined(__IEEE_FP__)	if (_isNaN(d)) {		errno = EDOM;		*expp = 0.0;		return d;	} else if (_isInfinity(d)) {		errno = ERANGE;		*expp = INT_MAX;		return (d < 0.0) ? -1.0 : 1.0;	}#endif	/* defined(__IEEE_FP__) */	if (d == 0.0) {		*expp = d;		return d;	}#endif	/* 0 */	(void)frexp(d, &binexp);		/* compute binary exponent */	if (modf((--binexp) / LOG2_10, &dexp) < 0.0)	/* get decimal exponent */		dexp -= 1.0;			/* adjust if negative */	decexp = (int)dexp;			/* convert to int */	/*	 * Scale d to desired range.	 * Avoid using _pow10(decexp) for decexp < 0 to avoid imprecision.	 */	if (decexp > 0)		d /= _pow10(decexp);	else if (decexp < 0)		d *= _pow10(-decexp);	if (d >= 10.) {				/* missed by 1, adjust */		++decexp;		d /= 10.;			/* not "d *= .1;" for precision */	}	/* Store the decimal exponent and return. */	*expp = decexp;	return d;}

⌨️ 快捷键说明

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