Files correlati : Ricompilazione Demo : [ ] Commento : Aggiunti i sorgenti per Greenleaf Math Library (gfm.dll) git-svn-id: svn://10.65.10.50/trunk@10079 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			253 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			253 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* DEC	*ConvAsciiToDecimalRound(dst,src1,nid)
 | 
						|
 *
 | 
						|
 * ARGUMENT
 | 
						|
 *	dst is a pointer to the	destination DEC	structure.
 | 
						|
 *	src1 is	a ptr to the ascii string to be	converted.
 | 
						|
 *
 | 
						|
 * DESCRIPTION
 | 
						|
 *	Converts an ascii string to an internal	format number
 | 
						|
 *   and puts it into the dst DEC structure.  The number is rounded
 | 
						|
 *   to	nid decimal places.
 | 
						|
 *
 | 
						|
 * SIDE	EFFECTS
 | 
						|
 *	None. The destination structure	is indeterminate if
 | 
						|
 *   an	overflow of significant	digits occured during conversion.
 | 
						|
 *
 | 
						|
 * RETURNS
 | 
						|
 *	Returns	a pointer to the dest structure	unless overflow.
 | 
						|
 *   Otherwise,	returns	a GM_NULL(a C false). On error,	the error
 | 
						|
 *   is	in wGMError, unless an error was already there.
 | 
						|
 *   Note that truncation of insignificant digits is not fatal,	but
 | 
						|
 *   sets a warning flag for the caller	to determine if	that is	fatal
 | 
						|
 *   for their application.
 | 
						|
 *
 | 
						|
 * POSSIBLE ERROR CODES
 | 
						|
 *
 | 
						|
 *	GM_NULLSTRING
 | 
						|
 *	GM_NAN
 | 
						|
 *	GM_CNVRE
 | 
						|
 *	GM_CNVRW
 | 
						|
 *	GM_INVALIDID
 | 
						|
 *
 | 
						|
 * AUTHOR
 | 
						|
 *  Andy Anderson   13-JAN-1987	 14:30
 | 
						|
 *   Copyright (C) 1987-1990 Greenleaf Software	Inc.  All rights reserved.
 | 
						|
 *
 | 
						|
 * MODIFICATIONS
 | 
						|
 *
 | 
						|
 *  Mark Nelson	  23-Jan-1990
 | 
						|
 *   Modified to handle	leading	and trailing whitespace, like atoi();
 | 
						|
 */
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include "gm.h"
 | 
						|
#include "gmsystem.h"
 | 
						|
 | 
						|
DEC	*ConvAsciiToDecimalRound(dst, s, nid )
 | 
						|
DEC	*dst;
 | 
						|
char	*s;
 | 
						|
int	nid;
 | 
						|
{
 | 
						|
	DEC	dx, *x=&dx;
 | 
						|
	int	digright;
 | 
						|
	int	sign, k, j, exp, expisn=0, equid, xtra=0;
 | 
						|
	mbool	trwarn=FALSE;
 | 
						|
	unsigned c10;
 | 
						|
	register int	i, fd;
 | 
						|
 | 
						|
	_MacStart(GM_ATODR);
 | 
						|
	fd = 0;
 | 
						|
	sign = 1;	/* assume a positive sign */
 | 
						|
 | 
						|
/* If he hands us a null string, _MacRet error to user */
 | 
						|
	if (!s)	{
 | 
						|
		_MacErr(GM_NULLSTRING);
 | 
						|
		_MacRet(GM_NULL); }
 | 
						|
 | 
						|
/* check for valid nid */
 | 
						|
	if ((nid < GM_MINID) ||	(nid > GM_MAXID))  {
 | 
						|
		_MacErr(GM_INVALIDID);
 | 
						|
		_MacRet(GM_NULL);
 | 
						|
	}
 | 
						|
 | 
						|
/* handle null pointers	*/
 | 
						|
	if (!dst)  {
 | 
						|
		_MacErr(GM_NULLPOINTER);
 | 
						|
		_MacRet(GM_NULL);
 | 
						|
	}
 | 
						|
 | 
						|
/* First strip any leading whitespace  */
 | 
						|
 | 
						|
	for (; s[fd] ==	' ' || s[fd] ==	'\t' ; fd++ ) ;
 | 
						|
 | 
						|
/* Then	check for an empty string */
 | 
						|
 | 
						|
	if (s[fd] == '\0')  {
 | 
						|
		_MacErr(GM_NULLSTRING);
 | 
						|
		_MacRet(GM_NULL);
 | 
						|
		}
 | 
						|
 | 
						|
/* fix sign */
 | 
						|
	for (; ((s[fd] == '-') || (s[fd] == '+')); fd++) {
 | 
						|
		if (s[fd] == '-')
 | 
						|
			sign = -1;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
/*  Strip leading zeroes from the string */
 | 
						|
	while (	s[fd] == '0' )
 | 
						|
	    fd++;
 | 
						|
 | 
						|
/*  Search for 'e' or 'E' signifying scientfic notation	*/
 | 
						|
	for ( j	= fd; ;	j++ ) {
 | 
						|
	    if ( s[j] == '\0' )
 | 
						|
		break;
 | 
						|
	    if ( s[j] == 'e' )
 | 
						|
		break;
 | 
						|
	    if ( s[j] == 'E' )
 | 
						|
		break;
 | 
						|
	    if ( s[j] == ' ' )
 | 
						|
		break;
 | 
						|
	    if ( s[j] == '\t' )
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
/*  If there is	an exponent, calculate it or _MacRet GM_NAN */
 | 
						|
	exp = 0;
 | 
						|
	if ((s[j] == 'e' || s[j] == 'E')) {
 | 
						|
		k=j+1;
 | 
						|
		if ((s[k]=='+')	|| (s[k]=='-'))	 {
 | 
						|
			expisn = (s[k]=='-') ? 1 : 0;
 | 
						|
			k++;
 | 
						|
		}
 | 
						|
		do  {
 | 
						|
			if ((s[k]<'0') || (s[k]>'9'))  {
 | 
						|
				_MacErr(GM_NAN);
 | 
						|
				_MacRet	(GM_NULL);
 | 
						|
			}
 | 
						|
			exp = 10*exp + s[k] - 0x30;
 | 
						|
			k++;
 | 
						|
		}  while (s[k] != 0 && s[k] != ' ' && s[k] != '\t' );
 | 
						|
		if (expisn)
 | 
						|
			exp = -exp;
 | 
						|
	}
 | 
						|
 | 
						|
/*  check for bad characters */
 | 
						|
	for (i=fd; i<j;	i++)
 | 
						|
		if (((s[i] < '0') || (s[i] > '9')) && (s[i] != '.')
 | 
						|
			&& (s[i] != ',')) {
 | 
						|
			_MacErr(GM_NAN);
 | 
						|
			_MacRet	(GM_NULL);
 | 
						|
		}
 | 
						|
 | 
						|
/* set equal to	0 */
 | 
						|
	_MacDZero(x);
 | 
						|
	x->dc.id = 0;
 | 
						|
 | 
						|
	if (fd == j)  {
 | 
						|
		_MacDCopy(dst, x);
 | 
						|
		_MacRet(dst);
 | 
						|
	}
 | 
						|
 | 
						|
/* everything else */
 | 
						|
	digright = 0;
 | 
						|
 | 
						|
/* digits before decimal point */
 | 
						|
	for (i=fd; (i<j	 ); i++)  {
 | 
						|
		if ((s[i] >= '0') && (s[i] <= '9'))  {
 | 
						|
			c10=s[i] - 0x30;
 | 
						|
			if (x->dc.sl[3]	< 3276L)
 | 
						|
				(void) _MulUnsArrP10AndAddInt(
 | 
						|
					 x->dc.sl, c10);
 | 
						|
			else  {
 | 
						|
				if((s[i] >= '5') && wfGMRound)
 | 
						|
					 /* round off */
 | 
						|
					(void) _IncrementUnsArr(
 | 
						|
						 x->dc.sl);
 | 
						|
				for (; ((s[i]!='.') && (i<j)); i++)
 | 
						|
					xtra++;
 | 
						|
				if (xtra+exp>0)	 {
 | 
						|
					_MacErr(GM_CNVRE);
 | 
						|
					_MacRet(GM_NULL);
 | 
						|
				}
 | 
						|
				i=j;
 | 
						|
				trwarn=TRUE;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if (s[i] == '.') {
 | 
						|
			i++;
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
/* digits after	decimal	point */
 | 
						|
	for (; i<j; i++) {
 | 
						|
		if ((s[i] >= '0') && (s[i] <= '9'))  {
 | 
						|
		/* after decimal point */
 | 
						|
			if ((digright-exp<nid)&&(x->dc.sl[3]<3276L)) {
 | 
						|
			/* room	for digit */
 | 
						|
				c10=s[i] - 0x30;
 | 
						|
				(void) _MulUnsArrP10AndAddInt(
 | 
						|
					 x->dc.sl, c10);
 | 
						|
				digright++;
 | 
						|
			}
 | 
						|
			else {
 | 
						|
			/* no room for digit */
 | 
						|
				if((s[i] >= '5') && wfGMRound) {
 | 
						|
					 /* round off */
 | 
						|
					(void) _IncrementUnsArr(
 | 
						|
						 x->dc.sl);
 | 
						|
				}
 | 
						|
				trwarn = TRUE;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if (s[i] == '.')  {
 | 
						|
			/* two decimal points */
 | 
						|
			_MacErr(GM_NAN);
 | 
						|
			_MacRet	(GM_NULL);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
/* adjust for exponential */
 | 
						|
	equid =	digright-xtra-exp;
 | 
						|
	x->ls.lid=nid;
 | 
						|
 | 
						|
	if (equid>nid)	{
 | 
						|
		trwarn=TRUE;
 | 
						|
		if (!_MacIsDecZ(x))  {
 | 
						|
			if (wfGMRound)
 | 
						|
				_DivUnsArrByPwrOf10( x->dc.sl,
 | 
						|
					5, equid-nid);
 | 
						|
			else
 | 
						|
				_DivUnsArrByPwrOf10Trunc( x->dc.sl,
 | 
						|
					5, equid-nid);
 | 
						|
			if (_MacIsDecZ(x))  {
 | 
						|
				_MacErr(GM_CNVRE);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if (equid<nid)	{
 | 
						|
		k=_MulUnsArrByPwrOf10( x->dc.sl, nid-equid, 5);
 | 
						|
		if ((k!=GM_SUCCESS) || (x->dc.msd!=0)
 | 
						|
			|| (x->dc.sl[3]	> 32767L))  {
 | 
						|
			_MacErr(GM_CNVRE);
 | 
						|
			_MacRet(GM_NULL);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
/* adjust for sign */
 | 
						|
	if (sign == -1)
 | 
						|
		_MacDChgs(x);
 | 
						|
 | 
						|
	_MacDCopy(dst, x);
 | 
						|
 | 
						|
	if (trwarn)
 | 
						|
		_MacErr(GM_CNVRW);
 | 
						|
 | 
						|
	_MacRet(dst);
 | 
						|
 | 
						|
}
 |