campo-sirio/gfm/atod.c
alex ba237a9d91 Patch level : no patch
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
2002-02-26 12:19:02 +00:00

246 lines
4.8 KiB
C
Executable File

/* DEC *ConvAsciiToDecimal(dst,src1)
*
* 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 id is the
* number of digits past the decimal point.
*
* 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
*
* 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 *ConvAsciiToDecimal( dst, s )
DEC *dst;
char *s;
{
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_ATOD);
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);
}
_MacOutVar(dst, 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<GM_MAXID)&&(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;
if ((equid>=GM_MINID) && (equid<=GM_MAXID))
x->ls.lid=equid;
if (equid>GM_MAXID) {
x->ls.lid=GM_MAXID;
trwarn=TRUE;
if (!_MacIsDecZ(x)) {
if (wfGMRound)
_DivUnsArrByPwrOf10( x->dc.sl,
5, equid-GM_MAXID);
else
_DivUnsArrByPwrOf10( x->dc.sl,
5, equid-GM_MAXID);
if (_MacIsDecZ(x)) {
_MacErr(GM_CNVRE);
}
}
}
if (equid<GM_MINID) {
k=_MulUnsArrByPwrOf10( x->dc.sl, GM_MINID-equid, 5);
if ((k!=GM_SUCCESS) || (x->dc.msd!=0)
|| (x->dc.sl[3] > 32767L)) {
_MacErr(GM_CNVRE);
_MacRet(GM_NULL);
}
x->dc.id=GM_MINID;
}
/* adjust for sign */
if (sign == -1)
_MacDChgs(x);
_MacDCopy(dst, x);
if (trwarn)
_MacErr(GM_CNVRW);
_MacRet(dst);
}