Cross Reference: sfstrtod.c
xref
: /
osnet-11
/
usr
/
src
/
lib
/
libast
/
common
/
sfio
/
sfstrtod.c
Home
History
Annotate
Line#
Navigate
Download
Search
only in
./
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
1
N/A
switch
(n)
1
N/A
{
case
-
3
:
return
.00
1
;
1
N/A
case
-
2
:
return
.0
1
;
1
N/A
case
-
1
:
return
.
1
;
1
N/A
case
0:
return
1
.;
1
N/A
case
1
:
return
10
.;
1
N/A
case
2
:
return
100
.;
1
N/A
case
3
:
return
1000
.;
1
N/A
}
1
N/A
1
N/A
if
(n < 0)
1
N/A
{
dval
= .000
1
;
1
N/A
for
(n +=
4
; n < 0; n +=
1
)
1
N/A
dval
/=
10
.;
1
N/A
}
1
N/A
else
1
N/A
{
dval
=
10000
.;
1
N/A
for
(n -=
4
; n > 0; n -=
1
)
1
N/A
dval
*=
10
.;
1
N/A
}
1
N/A
1
N/A
return
dval
;
1
N/A
}
1
N/A
1
N/A
#
if
__STD_C
1
N/A
Sfdouble_t
_sfstrtod
(
reg
const
char
* s,
char
**
retp
)
1
N/A
#
else
1
N/A
Sfdouble_t
_sfstrtod
(s,
retp
)
1
N/A
reg
char
* s;
/* string to convert */
1
N/A
char
**
retp
;
/* to return the remainder of string */
1
N/A
#
endif
1
N/A
{
1
N/A
reg
int
n, c, m;
1
N/A
reg
int
mode
,
fexp
,
sign
,
expsign
;
1
N/A
Sfdouble_t
dval
;
1
N/A
#
if
_lib_locale
1
N/A
int
decpoint
= 0;
1
N/A
int
thousand
= 0;
1
N/A
SFSETLOCALE
(&
decpoint
,&
thousand
);
1
N/A
#
else
1
N/A
#
define
decpoint
'.'
1
N/A
#
endif
1
N/A
1
N/A
/* skip initial blanks */
1
N/A
while
(
isspace
(*s))
1
N/A
++s;
1
N/A
1
N/A
/* get the sign */
1
N/A
if
((
sign
= (*s ==
'-'
)) || *s ==
'+'
)
1
N/A
s +=
1
;
1
N/A
1
N/A
mode
=
IPART
;
1
N/A
fexp
=
expsign
= 0;
1
N/A
dval
= 0.;
1
N/A
while
(*s)
1
N/A
{
/* accumulate a handful of the digits */
1
N/A
for
(m =
BATCH
, n = 0; m > 0; --m, ++s)
1
N/A
{
/* get and process a char */
1
N/A
c = *s;
1
N/A
if
(
isdigit
(c))
1
N/A
n =
10
*n + (c -
'0'
);
1
N/A
else
break
;
1
N/A
}
1
N/A
1
N/A
/* number of digits accumulated */
1
N/A
m =
BATCH
-m;
1
N/A
1
N/A
if
(
mode
==
IPART
)
1
N/A
{
/* doing the integer part */
1
N/A
if
(
dval
== 0.)
1
N/A
dval
= (
Sfdouble_t
)n;
1
N/A
else
dval
=
dval
*
sfpow10
(m) + (
Sfdouble_t
)n;
1
N/A
}
1
N/A
else
if
(
mode
==
FPART
)
1
N/A
{
/* doing the fractional part */
1
N/A
fexp
-= m;
1
N/A
if
(n > 0)
1
N/A
dval
+= n*
sfpow10
(
fexp
);
1
N/A
}
1
N/A
else
if
(n)
1
N/A
{
/* doing the exponent part */
1
N/A
if
(
expsign
)
1
N/A
n = -n;
1
N/A
dval
*=
sfpow10
(n);
1
N/A
}
1
N/A
1
N/A
if
(!c)
1
N/A
break
;
1
N/A
1
N/A
if
(m <
BATCH
)
1
N/A
{
/* detected a non-digit */
1
N/A
if
(c ==
decpoint
)
1
N/A
{
/* start the fractional part or no match */
1
N/A
if
(
mode
!=
IPART
)
1
N/A
break
;
1
N/A
mode
=
FPART
;
1
N/A
s +=
1
;
1
N/A
}
1
N/A
else
if
(c ==
'e'
|| c ==
'E'
)
1
N/A
{
if
(
mode
==
EPART
)
1
N/A
break
;
1
N/A
mode
=
EPART
;
1
N/A
c = *++s;
1
N/A
if
((
expsign
= (c ==
'-'
)) || c ==
'+'
)
1
N/A
s +=
1
;
1
N/A
}
1
N/A
else
break
;
1
N/A
}
1
N/A
}
1
N/A
1
N/A
if
(
retp
)
1
N/A
*
retp
= (
char
*)s;
1
N/A
return
sign
? -
dval
:
dval
;
1
N/A
}