1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 /* Convert a Sfdouble_t value represented in an ASCII format into
25 ** the internal Sfdouble_t representation.
27 ** Written by Kiem-Phong Vo.
30 #define BATCH (2*sizeof(int)) /* accumulate this many digits at a time */
31 #define IPART 0 /* doing integer part */
32 #define FPART 1 /* doing fractional part */
33 #define EPART 2 /* doing exponent part */
36 static Sfdouble_t
sfpow10(reg
int n
)
38 static Sfdouble_t
sfpow10(n
)
45 { case -3: return .001;
56 for(n
+= 4; n
< 0; n
+= 1)
61 for(n
-= 4; n
> 0; n
-= 1)
69 Sfdouble_t
_sfstrtod(reg
const char* s
, char** retp
)
71 Sfdouble_t
_sfstrtod(s
,retp
)
72 reg
char* s
; /* string to convert */
73 char** retp
; /* to return the remainder of string */
77 reg
int mode
, fexp
, sign
, expsign
;
82 SFSETLOCALE(&decpoint
,&thousand
);
87 /* skip initial blanks */
92 if((sign
= (*s
== '-')) || *s
== '+')
99 { /* accumulate a handful of the digits */
100 for(m
= BATCH
, n
= 0; m
> 0; --m
, ++s
)
101 { /* get and process a char */
104 n
= 10*n
+ (c
- '0');
108 /* number of digits accumulated */
112 { /* doing the integer part */
114 dval
= (Sfdouble_t
)n
;
115 else dval
= dval
*sfpow10(m
) + (Sfdouble_t
)n
;
117 else if(mode
== FPART
)
118 { /* doing the fractional part */
121 dval
+= n
*sfpow10(fexp
);
124 { /* doing the exponent part */
134 { /* detected a non-digit */
136 { /* start the fractional part or no match */
142 else if(c
== 'e' || c
== 'E')
147 if((expsign
= (c
== '-')) || c
== '+')
156 return sign
? -dval
: dval
;