ba237a9d91
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
246 lines
4.8 KiB
C
Executable File
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);
|
|
}
|