non-AT&T implementations of frexp.c in machine/gen/frexp.c
[unix-history] / usr / src / lib / libc / hp300 / stdlib / atof.c
CommitLineData
2a9e442d
KB
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)
13static char sccsid[] = "@(#)atof.c 5.1 (Berkeley) %G%";
14#endif /* LIBC_SCCS and not lint */
15
16#include <ctype.h>
17
18double _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 */
27struct {
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
42double _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
57double
58atof(p)
59register 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}