You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
1.0 KiB
C

#include "scan.h"
#ifdef __GNUC__
static inline int isdigit(int c) { return (c>='0' && c<='9'); }
#else
#include <ctype.h>
#endif
size_t scan_double(const char *in, double *dest) {
double d=0;
register const char *c=in;
char neg=0;
switch (*c) {
case '-': neg=1; /* fall through */
case '+': c++; break;
default: break;
}
while (isdigit(*c)) {
d=d*10+(*c-'0');
++c;
}
if (*c=='.') {
double factor=.1;
while (isdigit(*++c)) {
d=d+(factor*(*c-'0'));
factor/=10;
}
}
if ((*c|32)=='e') {
int exp=0;
char neg=0;
if (c[1]<'0') {
switch (*c) {
case '-': neg=1; /* fall through */
case '+': c++; break;
default:
d=0;
c=in;
goto done;
}
}
while (isdigit(*++c))
exp=exp*10+(*c-'0');
if (neg)
while (exp) { /* XXX: this introduces rounding errors */
d/=10; --exp;
}
else
while (exp) { /* XXX: this introduces rounding errors */
d*=10; --exp;
}
}
done:
*dest=(neg?-d:d);
return (size_t)(c-in);
}