Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/gnu/lib/aton.c
There are no other files named aton.c in the archive.
7-May-84 09:28:27-EDT,4742;000000000001
Received: from MIT-MC by MIT-OZ via Chaosnet; 7 May 84 09:28-EDT
Received: From bostonu.csnet by csnet-relay; 7 May 84 9:12 EDT
Received: by csvaxa.ARPA (4.12/4.7)
id AA00824; Sun, 6 May 84 19:37:00 edt
Date: Sun, 6 May 84 19:37:00 edt
From: God <root%[email protected]>
Message-Id: <[email protected]>
To: [email protected]
Subject: atonum.c (should probably be called atof.c)
#ifdef DEBUG
#include <stdio.h>
#else
#define NULL 0
#endif
#define REGARG register
#define REGISTER register
#define MAXBASE 36
/*
* ASCII VERSION!! will not work directly w/ EBCDIC
*/
#define islower(c) (((c) >= 'a') && ((c) <= 'z'))
#define isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
#define isdigit(c) (((c) >= '0') && ((c) <= '9'))
#define isalpha(c) (islower(c) || isupper(c))
#define toupper(c) (islower(c) ? (c) - ' ' : c)
/*
* aton - general purpose conversion of a number from a string
* res: ptr to result cell
* s: string to extract num from
* b: base, if zero then use C rules (0nnn,0xnnn)
* return: NULL if err otherwise ptr to char that stopped
* the parse.
*
* AUTHOR
* Barry Shein, Boston University
*/
char *
aton(res,s,b) long *res ; REGARG char *s ; int b ;
{
REGISTER long i = 0 ;
register int c ;
int sign = 1 ;
if((b < 0) || (b > MAXBASE)) return(NULL) ;
/*
* Skip white space
*/
while(*s <= ' ')
if(*s++ == '\0') return(NULL) ;
/*
* Check for - or +
*/
if(*s == '-')
{
++s ;
sign = -1 ;
}
else if(*s == '+') ++s ;
/*
* If base is zero determine base from string a la C
*/
if(b == 0)
{
if(*s == '0')
{
++s ;
if(toupper(*s) == 'X')
{
b = 16 ;
++s ;
}
else b = 8 ;
}
else b = 10 ;
}
for(; c = *s ; s++)
{
if(isdigit(c))
{
c -= '0' ;
if(c >= b) break ;
}
else if(isalpha(c))
{
c = toupper(c) - 'A' + 10 ;
if(c >= b) break ;
}
else break ;
i = i * b + c ;
}
*res = i * sign ;
return(s) ;
}
/*
* atoi - Standard Ascii TO Integer, base 10, returns int
*/
int
atoi(s) char *s ;
{
long i = 0 ;
aton(&i,s,10) ;
return((int) i) ;
}
/*
* atol - standard Ascii TO Long, base 10, returns long
*/
long
atol(s) char *s ;
{
long i = 0 ;
aton(&i,s,10) ;
return(i) ;
}
/*
* atof - accept a number of the form:
* (and ignores leading white space)
*
* null ::=
* digit ::= 0|1|2|3|4|5|6|7|8|9
* digits ::= <digit>*
* DIGITS ::= <digit>+
* sign ::= <null> | + | -
* -------------------------------
* accepted:
* -------------------------------
* integer ::= <sign><DIGITS>
* real ::= <integer> . <digits> | <null> . <DIGITS>
* epart ::= e <integer> | E <integer>
* float ::= <integer> <epart> | <real> <epart>
*
* Always returned as a double
*
* There is no particular attempt to reduce mpys/divs
* those machines that are still out there (eg. PDP11/Small)
* that shun floating point arithmetic might rethink this routine.
*/
double
atof(s) REGARG char *s ;
{
REGISTER char *cp ;
long ipart, epart ;
int neg = 0 ;
double res, powr ;
while(*s <= ' ') if(*s == '\0') return(0.0) ;
/*
* Need to handle sign here due to '-.3' or '-0.3'
* which aton won't pick up ;
*/
if(*s == '-')
{
++neg ;
++s ;
}
cp = s ;
/*
* get ipart handling '.n' case
*/
if((s = aton(&ipart,s,10)) == cp)
{
if(*s == '.') ipart = 0 ;
else return(0.0) ;
}
res = (double) ipart ;
/*
* either we find a '.' or e|E or done
*/
if(*s == '.')
{
++s ;
for(powr = 10.0 ; isdigit(*s) ; s++,powr *= 10.0)
res += ((float) (*s - '0'))/powr ;
}
/*
* In either case (.) handle E part
*/
if(toupper(*s) == 'E')
{
++s ;
aton(&epart,s,10) ;
if(epart > 0)
while(epart--) res *= 10.0 ;
else while(epart++) res /= 10.0 ;
}
/*
* fix sign
*/
if(neg) res = -res ;
return(res) ;
}
#ifdef DEBUG
/*
* Test driver
*/
main()
{
char *s ;
int i ;
long res ;
char buf[1024] ;
double atof() ;
s = "100" ;
for(i=2 ; i <= MAXBASE ; i++)
{
aton(&res,s,i) ;
printf("%s as base %d => %d\n",s,i,res) ;
}
s = "aBc" ;
for(i=11 ; i <= MAXBASE ; i++)
{
aton(&res,s,i) ;
printf("%s as base %d => %d\n",s,i,res) ;
}
s = "-15" ;
aton(&res,s,10) ;
printf("Should be %s: %d\n",s,res) ;
s = "0x1a" ;
aton(&res,s,0) ;
printf("Should be %s: 0x%x\n",s,res) ;
s = "0200" ;
aton(&res,s,0) ;
printf("Should be %s: 0%o\n",s,res) ;
printf("Test atoi(\" -12\") => %d\n",atoi(" -12")) ;
for(;;)
{
printf("Number for atof: ") ;
if(gets(buf) == NULL) break ;
printf("(15.6f) %15.6f\n",atof(buf)) ;
}
}
#endif DEBUG