xref: /csrg-svn/lib/libc/hp300/stdlib/atof.c (revision 41806)
1*41806Sbostic /*-
2*41806Sbostic  * Copyright (c) 1990 The Regents of the University of California.
3*41806Sbostic  * All rights reserved.
4*41806Sbostic  *
5*41806Sbostic  * This code is derived from software contributed to Berkeley by
6*41806Sbostic  * the Systems Programming Group of the University of Utah Computer
7*41806Sbostic  * Science Department.
8*41806Sbostic  *
9*41806Sbostic  * %sccs.include.redist.c%
10*41806Sbostic  */
11*41806Sbostic 
12*41806Sbostic #if defined(LIBC_SCCS) && !defined(lint)
13*41806Sbostic static char sccsid[] = "@(#)atof.c	5.1 (Berkeley) 05/12/90";
14*41806Sbostic #endif /* LIBC_SCCS and not lint */
15*41806Sbostic 
16*41806Sbostic #include <ctype.h>
17*41806Sbostic 
18*41806Sbostic double _twoemax =
19*41806Sbostic #ifdef IEEE
20*41806Sbostic 	9007199254740992.;	/*2^53*/
21*41806Sbostic #else
22*41806Sbostic 	72057594037927936.;	/*2^56*/
23*41806Sbostic #endif
24*41806Sbostic 
25*41806Sbostic #ifdef hp300
26*41806Sbostic /* attempt to be as exact as possible */
27*41806Sbostic struct {
28*41806Sbostic 	long d_high;
29*41806Sbostic 	long d_low;
30*41806Sbostic } _exp5[] = {
31*41806Sbostic 	{ 0x40140000, 0x00000000 },	/* 5 */
32*41806Sbostic 	{ 0x40390000, 0x00000000 },	/* 25 */
33*41806Sbostic 	{ 0x40838800, 0x00000000 },	/* 625 */
34*41806Sbostic 	{ 0x4117d784, 0x00000000 },	/* 390625 */
35*41806Sbostic 	{ 0x4241c379, 0x37e08000 },	/* 152587890625 */
36*41806Sbostic 	{ 0x4493b8b5, 0xb5056e17 },	/* 2.3283064365387e+022 */
37*41806Sbostic 	{ 0x49384f03, 0xe93ff9f6 },	/* 5.42101086242753e+044 */
38*41806Sbostic 	{ 0x52827748, 0xf9301d33 },	/* 2.93873587705572e+089 */
39*41806Sbostic 	{ 0x65154fdd, 0x7f73bf3f }	/* 8.63616855509445e+178 */
40*41806Sbostic };
41*41806Sbostic #else
42*41806Sbostic double	_exp5[]	= {
43*41806Sbostic 	5.,
44*41806Sbostic 	25.,
45*41806Sbostic 	625.,
46*41806Sbostic 	390625.,
47*41806Sbostic 	152587890625.,
48*41806Sbostic 	23283064365386962890625.,
49*41806Sbostic #ifdef IEEE
50*41806Sbostic 	5.4210108624275231e+044,
51*41806Sbostic 	2.9387358770557196e+089,
52*41806Sbostic 	8.6361685550944492e+178,
53*41806Sbostic #endif
54*41806Sbostic };
55*41806Sbostic #endif
56*41806Sbostic 
57*41806Sbostic double
58*41806Sbostic atof(p)
59*41806Sbostic register char *p;
60*41806Sbostic {
61*41806Sbostic 	extern double ldexp();
62*41806Sbostic 	register c, exp = 0, eexp = 0;
63*41806Sbostic 	double fl = 0, flexp = 1.0;
64*41806Sbostic 	int bexp, neg = 1, negexp = 1;
65*41806Sbostic 
66*41806Sbostic 	while((c = *p++) == ' ');
67*41806Sbostic 	if (c == '-') neg = -1;	else if (c == '+'); else --p;
68*41806Sbostic 
69*41806Sbostic 	while ((c = *p++), isdigit(c))
70*41806Sbostic 		if (fl < _twoemax) fl = 10*fl + (c-'0'); else exp++;
71*41806Sbostic 	if (c == '.')
72*41806Sbostic 	while ((c = *p++), isdigit(c))
73*41806Sbostic 		if (fl < _twoemax)
74*41806Sbostic 		{
75*41806Sbostic 			fl = 10*fl + (c-'0');
76*41806Sbostic 			exp--;
77*41806Sbostic 		}
78*41806Sbostic 	if ((c == 'E') || (c == 'e'))
79*41806Sbostic 	{
80*41806Sbostic 		if ((c= *p++) == '+'); else if (c=='-') negexp = -1; else --p;
81*41806Sbostic 		while ((c = *p++), isdigit(c)) eexp = 10*eexp + (c-'0');
82*41806Sbostic 		if (negexp < 0) eexp = -eexp; exp += eexp;
83*41806Sbostic 	}
84*41806Sbostic 	bexp = exp;
85*41806Sbostic 	if (exp < 0) exp = -exp;
86*41806Sbostic 
87*41806Sbostic 	for (c = 0; c < sizeof(_exp5)/sizeof(_exp5[0]); c++)
88*41806Sbostic 	{
89*41806Sbostic #ifdef hp300
90*41806Sbostic 		if (exp & 01) flexp *= *(double *)&_exp5[c];
91*41806Sbostic #else
92*41806Sbostic 		if (exp & 01) flexp *= _exp5[c];
93*41806Sbostic #endif
94*41806Sbostic 		exp >>= 1; if (exp == 0) break;
95*41806Sbostic 	}
96*41806Sbostic 
97*41806Sbostic 	if (bexp < 0) fl /= flexp; else fl *= flexp;
98*41806Sbostic 	fl = ldexp(fl, bexp);
99*41806Sbostic 	if (neg < 0) return(-fl); else return(fl);
100*41806Sbostic }
101