Cross Reference: sfstrtod.c
xref
: /
osnet-11
/
usr
/
src
/
lib
/
libast
/
common
/
sfio
/
sfstrtod.c
Home
History
Annotate
Line#
Navigate
Download
Search
only in
./
sfstrtod.c revision 1
1
N/A
/***********************************************************************
1
N/A
* *
1
N/A
* This software is part of the ast package *
1
N/A
* Copyright (c) 1985-2011 AT&T Intellectual Property *
1
N/A
* and is licensed under the *
1
N/A
* Common Public License, Version 1.0 *
1
N/A
* by AT&T Intellectual Property *
1
N/A
* *
1
N/A
* A copy of the License is available at *
1
N/A
*
http://www.opensource.org/licenses/cpl1.0.txt
*
1
N/A
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1
N/A
* *
1
N/A
* Information and Software Systems Research *
1
N/A
* AT&T Research *
1
N/A
* Florham Park NJ *
1
N/A
* *
1
N/A
* Glenn Fowler <gsf@research.att.com> *
1
N/A
* David Korn <dgk@research.att.com> *
1
N/A
* Phong Vo <kpv@research.att.com> *
1
N/A
* *
1
N/A
***********************************************************************/
1
N/A
#
include
"
sfhdr.h
"
1
N/A
1
N/A
/* Convert a Sfdouble_t value represented in an ASCII format into
1
N/A
** the internal Sfdouble_t representation.
1
N/A
**
1
N/A
** Written by Kiem-Phong Vo.
1
N/A
*/
1
N/A
1
N/A
#
define
BATCH
(
2
*
sizeof
(
int
))
/* accumulate this many digits at a time */
1
N/A
#
define
IPART
0
/* doing integer part */
1
N/A
#
define
FPART
1
/* doing fractional part */
1
N/A
#
define
EPART
2
/* doing exponent part */
1
N/A
1
N/A
#
if
__STD_C
1
N/A
static
Sfdouble_t
sfpow10
(
reg
int
n)
1
N/A
#
else
1
N/A
static
Sfdouble_t
sfpow10
(n)
1
N/A
reg
int
n;
1
N/A
#
endif
1
N/A
{
1
N/A
Sfdouble_t
dval
;
1
N/A
switch
(n)
{
case
-
3
:
return
.00
1
;
case
-
2
:
return
.0
1
;
case
-
1
:
return
.
1
;
case
0:
return
1
.;
case
1
:
return
10
.;
case
2
:
return
100
.;
case
3
:
return
1000
.;
}
if
(n < 0)
{
dval
= .000
1
;
for
(n +=
4
; n < 0; n +=
1
)
dval
/=
10
.;
}
else
{
dval
=
10000
.;
for
(n -=
4
; n > 0; n -=
1
)
dval
*=
10
.;
}
return
dval
;
}
#
if
__STD_C
Sfdouble_t
_sfstrtod
(
reg
const
char
* s,
char
**
retp
)
#
else
Sfdouble_t
_sfstrtod
(s,
retp
)
reg
char
* s;
/* string to convert */
char
**
retp
;
/* to return the remainder of string */
#
endif
{
reg
int
n, c, m;
reg
int
mode
,
fexp
,
sign
,
expsign
;
Sfdouble_t
dval
;
#
if
_lib_locale
int
decpoint
= 0;
int
thousand
= 0;
SFSETLOCALE
(&
decpoint
,&
thousand
);
#
else
#
define
decpoint
'.'
#
endif
/* skip initial blanks */
while
(
isspace
(*s))
++s;
/* get the sign */
if
((
sign
= (*s ==
'-'
)) || *s ==
'+'
)
s +=
1
;
mode
=
IPART
;
fexp
=
expsign
= 0;
dval
= 0.;
while
(*s)
{
/* accumulate a handful of the digits */
for
(m =
BATCH
, n = 0; m > 0; --m, ++s)
{
/* get and process a char */
c = *s;
if
(
isdigit
(c))
n =
10
*n + (c -
'0'
);
else
break
;
}
/* number of digits accumulated */
m =
BATCH
-m;
if
(
mode
==
IPART
)
{
/* doing the integer part */
if
(
dval
== 0.)
dval
= (
Sfdouble_t
)n;
else
dval
=
dval
*
sfpow10
(m) + (
Sfdouble_t
)n;
}
else
if
(
mode
==
FPART
)
{
/* doing the fractional part */
fexp
-= m;
if
(n > 0)
dval
+= n*
sfpow10
(
fexp
);
}
else
if
(n)
{
/* doing the exponent part */
if
(
expsign
)
n = -n;
dval
*=
sfpow10
(n);
}
if
(!c)
break
;
if
(m <
BATCH
)
{
/* detected a non-digit */
if
(c ==
decpoint
)
{
/* start the fractional part or no match */
if
(
mode
!=
IPART
)
break
;
mode
=
FPART
;
s +=
1
;
}
else
if
(c ==
'e'
|| c ==
'E'
)
{
if
(
mode
==
EPART
)
break
;
mode
=
EPART
;
c = *++s;
if
((
expsign
= (c ==
'-'
)) || c ==
'+'
)
s +=
1
;
}
else
break
;
}
}
if
(
retp
)
*
retp
= (
char
*)s;
return
sign
? -
dval
:
dval
;
}