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

📄 floatlib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* floatLib.c - floating-point formatting and scanning library *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02f,19oct01,dcb  Fix the routine title line to match the coding conventions.02e,14mar99,jdi  doc: removed refs to config.h and/or configAll.h (SPR 25663).02d,30jul96,dbt  fixed floatScan to avoid loose of precision (SPR #3829). 		 Updated copyright.02c,01dec94,ism  fixed alt 'g' format bug.  Added in-line docs.02b,06oct94,ism  fixed %.XXg outputting more than XX sig figs (SPR#3695)02a,27jan93,jdi  documentation cleanup for 5.1; fixed SPR 1399.01z,30jul92,kdl  Restored 01w changes (clobbered by 01x); removed fpTypeGet()		 and isInf, isNan, & isZero macros.01y,30jul92,rrr  Removed decl of DOUBLE (now in mathLibP.h)01x,30jul92,smb  (Accidental checkin.)01w,30jul92,kdl  Significantly reworked for new ansi fio; moved frexp(), 	   +jcf	 ldexp(), modf() to src/libc/math; moved DOUBLE union 		 definition to mathP.h; removed special handling for i960.01v,18jul92,smb  Changed errno.h to errnoLib.h.01u,13jul92,smb  frexp, ldexp, modf now in libc for the SPARC (temporary change)01t,26may92,rrr  the tree shuffle01s,04mar92,wmd  placed declaration of atof() outside of 960 conditional,		 included string.h.01r,10dec91,gae  added includes for ANSI.01q,28oct91,wmd  added in type casting for *pCh in floatScan as per Intel mods.01p,04oct91,rrr  passed through the ansification filter                  -changed functions to ansi style		  -changed includes to have absolute path from h/		  -fixed #else and #endif		  -changed VOID to void		  -changed copyright notice01o,09jun91,del  integration of mods by intel for interfacing to gnu960		 libraries and fix bugs from 01m.01n,05apr91,jdi	 documentation -- removed header parens and x-ref numbers;		 doc review by dnw.01m,25mar91,del  interfaces to gnu960 flt. pt. libraries for I960CA01l,07feb91,jaa	 documentation cleanup.01k,23aug90,elr  Documentation01j,01aug90,dnw  fixed bug in floatScan scanning <nn>e<nn> format numbers.		 changed floatFormat to take pVaList instead of vaList.01i,04jun90,dnw  changed floatFormat to take a vararg va_list instead of a		   double arg, so that fioLib can be free of all flt pt refs.		 replaced floatAtoF with new routine floatScan, written		   from scratch, with our own algorithm for scanning flt pt		   numbers, designed to work with scanField() in fioLib.		 fixed bug incorrectly scanning large numbers that are too big.		 fixed documentation.		 make ecvtb, fcvtb, gcvtb be "no manual".01h,07mar90,jdi  documentation cleanup.01g,20apr89,dab  fixed precision bug in cvtb().		 documentation touchup in fcvtb() and cvtb().01f,05jun88,dnw  changed name from fltLib to floatLib.01e,30may88,dnw  changed to v4 names.01d,28may88,dnw  changed atof() to fltAtoF().01c,17mar88,gae  added 'E' and 'G' format specifiers.01b,05nov87,jlf  documentation01a,01aug87,gae  written/extracted from fioLib.c.*//*DESCRIPTIONThis library provides the floating-point I/O formatting and scanningsupport routines.The floating-point formatting and scanning support routines are notdirectly callable; they are connected to call-outs in the printf()/scanf()family of functions in fioLib.  This is done dynamically by the routinefloatInit(), which is called by the root task, usrRoot(), in usrConfig.cwhen the configuration macro INCLUDE_FLOATING_POINT is defined.If this option is omitted (i.e., floatInit() is not called), floating-pointformat specifications in printf() and sscanf() are not supported.INCLUDE FILES: math.hSEE ALSO: fioLib*/#include "vxWorks.h"#include "vwModNum.h"#include "fioLib.h"#include "string.h"#include "stdlib.h"#include "ctype.h"#include "string.h"#include "errnoLib.h"#include "math.h"#include "limits.h"#include "stdarg.h"#include "fioLib.h"#include "private/floatioP.h"#include "private/mathP.h"/* macros */#define	to_digit(c)	((c) - '0')#define is_digit(c)	((unsigned)to_digit(c) <= 9)#define	to_char(n)	((n) + '0')/* forward static functions */LOCAL int 	floatFormat (va_list *pVaList, int precision, BOOL doAlt, 		             int fmtSym, BOOL *pDoSign, char *pBufStart, 		             char *pBufEnd);LOCAL BOOL 	floatScan (int *pReturn, int returnSpec, int fieldwidth,		           FUNCPTR getRtn, int getArg, int *pCh, int *pNchars);LOCAL int 	cvt (double number, int prec, BOOL doAlt, int fmtch,	       	     BOOL *pDoSign, char *startp, char *endp);LOCAL char *	exponentCvt (char *p, int exp, int fmtch);LOCAL char *	roundCvt (double fract, int *exp, char *start, char *end, 			  char ch, BOOL *pDoSign);LOCAL int	floatFpTypeGet ( double v, double * r);/********************************************************************************* floatInit - initialize floating-point I/O support** This routine must be called if floating-point format specifications are* to be supported by the printf()/scanf() family of routines.* If the configuration macro INCLUDE_FLOATING_POINT is defined, it is called* by the root task, usrRoot(), in usrConfig.c.** RETURNS: N/A*/void floatInit (void)    {    fioFltInstall ((FUNCPTR)floatFormat, (FUNCPTR)floatScan);    }/********************************************************************************* floatFormat - format arg for output** This routine converts from a floating-point value to an ASCII representation.* The <fmtSym> parameter indicates the format type desired; the actual work* is done in cvt.** RETURNS: number of characters placed in buffer*/LOCAL int floatFormat     (    va_list *	pVaList,	/* vararg list */    int		precision,	/* precision */    BOOL	doAlt, 		/* doAlt boolean */    int		fmtSym,		/* format symbol */    BOOL *	pDoSign, 	/* where to fill in doSign result */    char *	pBufStart,	/* buffer start */    char *	pBufEnd		/* buffer end */    )    {    double dbl = (double) va_arg (*pVaList, double);    *pDoSign = FALSE;				/* assume no sign needed */    if (isInf(dbl)) 				/* infinite? */	{	strcpy (pBufStart, "Inf");		/* fill in the string */	if (dbl < 0.0)				/* less than 0.0 */	    *pDoSign = TRUE;			/* we need a sign */	return (-3);				/* length will be three */	}    if (isNan(dbl)) 				/* not a number? */	{	strcpy (pBufStart, "NaN");		/* fill in the string */	return (-3);				/* length will be three */	}    return (cvt (dbl, precision, doAlt, fmtSym, pDoSign, pBufStart, pBufEnd));    }/******************************************************************************* * cvt - helper function for floatFormat* * RETURNS: */LOCAL int cvt    (    double	number,    FAST int	prec,    BOOL	doAlt,    int		fmtch,    BOOL *	pDoSign,    char *	startp,    char *	endp    )    {    FAST char *	p;    FAST char *	t;    FAST double fract;    int 	dotrim;    int 	expcnt;    int 	gformat;	int		nonZeroInt=FALSE;    double 	integer;    double	tmp;    dotrim = expcnt = gformat = 0;    if (number < 0) 	{	number = -number;	*pDoSign = TRUE;	}    else	*pDoSign = FALSE;    fract = modf(number, &integer);	if(integer!=(double)0.0)		nonZeroInt=TRUE;    t = ++startp;			/* get an extra slot for rounding. */    /* 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 || doAlt)		    *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 = roundCvt (fract, (int *)NULL, startp, t - 1,				       (char)0, pDoSign);		    }		for (; prec--; *t++ = '0')		    ;		break;	case 'e':	case 'E':eformat:	if (expcnt) 		    {		    *t++ = *++p;		    if (prec || doAlt)			*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 = roundCvt((double)0, &expcnt, startp, t - 1, *p,				       pDoSign);			}		    --expcnt;	/* adjust expcnt for dig. in front of decimal */		    }		/* 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 || doAlt)			*t++ = '.';		    }		else 		    {		    *t++ = '0';		    if (prec || doAlt)			*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 = roundCvt(fract, &expcnt, startp, t - 1,(char)0,				          pDoSign);		    }		for (; prec--; *t++ = '0')	/* if requires more precision */		    ;		/* unless alternate flag, trim any g/G format trailing 0's */		if (gformat && !doAlt) 		    {		    while (t > startp && *--t == '0')			;		    if (*t == '.')			--t;		    ++t;		    }		t = exponentCvt (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;		    }		/*

⌨️ 快捷键说明

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