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