File: scan_double.c

package info (click to toggle)
libowfat 0.34-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,288 kB
  • sloc: ansic: 20,181; makefile: 16
file content (56 lines) | stat: -rw-r--r-- 1,044 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#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);
}