Commit | Line | Data |
---|---|---|
15637ed4 RG |
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 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in the | |
16 | * documentation and/or other materials provided with the distribution. | |
17 | * 3. All advertising materials mentioning features or use of this software | |
18 | * must display the following acknowledgement: | |
19 | * This product includes software developed by the University of | |
20 | * California, Berkeley and its contributors. | |
21 | * 4. Neither the name of the University nor the names of its contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
35 | * SUCH DAMAGE. | |
36 | * | |
37 | * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE | |
38 | * -------------------- ----- ---------------------- | |
39 | * CURRENT PATCH LEVEL: 2 00108 | |
40 | * -------------------- ----- ---------------------- | |
41 | * | |
42 | * 27 Feb 93 Joerg Wunsch Implement strtod, fix atof. | |
43 | * 28 Mar 93 Jordan Hubbard Fix stdtod bug with endp, remove warnings. | |
44 | * | |
45 | */ | |
46 | ||
47 | #if defined(LIBC_SCCS) && !defined(lint) | |
48 | static char sccsid[] = "@(#)atof.c 5.2 (Berkeley) 4/12/91"; | |
49 | #endif /* LIBC_SCCS and not lint */ | |
50 | ||
51 | /* | |
52 | * simple atof() for IEEE 754 architectures | |
53 | */ | |
54 | ||
55 | #include <machine/endian.h> | |
56 | #include <stdlib.h> | |
57 | #include <math.h> | |
58 | #include <ctype.h> | |
59 | #include <errno.h> | |
60 | #include <stdio.h> | |
61 | ||
62 | static double twoemax = 9007199254740992.; /*2^53*/ | |
63 | ||
64 | /* attempt to be as exact as possible */ | |
65 | static struct { | |
66 | long low_word; | |
67 | long high_word; | |
68 | } exp5[] = { | |
69 | #if BYTE_ORDER == BIG_ENDIAN | |
70 | { 0x40140000, 0x00000000 }, /* 5 */ | |
71 | { 0x40390000, 0x00000000 }, /* 25 */ | |
72 | { 0x40838800, 0x00000000 }, /* 625 */ | |
73 | { 0x4117d784, 0x00000000 }, /* 390625 */ | |
74 | { 0x4241c379, 0x37e08000 }, /* 152587890625 */ | |
75 | { 0x4493b8b5, 0xb5056e17 }, /* 2.3283064365387e+022 */ | |
76 | { 0x49384f03, 0xe93ff9f5 }, /* 5.42101086242753e+044 */ | |
77 | { 0x52827748, 0xf9301d32 }, /* 2.93873587705572e+089 */ | |
78 | { 0x65154fdd, 0x7f73bf3b } /* 8.63616855509445e+178 */ | |
79 | #else /* BYTE_ORDER == LITTLE_ENDIAN */ | |
80 | { 0x00000000, 0x40140000 }, /* 5 */ | |
81 | { 0x00000000, 0x40390000 }, /* 25 */ | |
82 | { 0x00000000, 0x40838800 }, /* 625 */ | |
83 | { 0x00000000, 0x4117d784 }, /* 390625 */ | |
84 | { 0x37e08000, 0x4241c379 }, /* 152587890625 */ | |
85 | { 0xb5056e17, 0x4493b8b5 }, /* 2.3283064365387e+022 */ | |
86 | { 0xe93ff9f5, 0x49384f03 }, /* 5.42101086242753e+044 */ | |
87 | { 0xf9301d32, 0x52827748 }, /* 2.93873587705572e+089 */ | |
88 | { 0x7f73bf3b, 0x65154fdd } /* 8.63616855509445e+178 */ | |
89 | #endif | |
90 | }; | |
91 | ||
92 | double | |
93 | strtod(p, endp) | |
94 | register const char *p; | |
95 | char **endp; | |
96 | { | |
97 | register int c; | |
98 | register int exp = 0; | |
99 | register int eexp = 0; | |
100 | double fl = 0; | |
101 | double flexp = 1.0; | |
102 | int bexp; | |
103 | int neg = 1; | |
104 | int negexp = 1; | |
105 | const char *oldp = p; | |
106 | ||
107 | while (isspace(*p)) | |
108 | ++p; | |
109 | ||
110 | if ((c = *p++) == '-') | |
111 | neg = -1; | |
112 | else if (c == '+') | |
113 | /* skip it */; | |
114 | else | |
115 | --p; | |
116 | ||
117 | while ((c = *p++) && isdigit(c)) | |
118 | if (fl < twoemax) | |
119 | fl = 10 * fl + (c-'0'); | |
120 | else | |
121 | ++exp; | |
122 | ||
123 | if (c == '.') | |
124 | while ((c = *p++) && isdigit(c)) | |
125 | if (fl < twoemax) { | |
126 | fl = 10 * fl + (c-'0'); | |
127 | --exp; | |
128 | } | |
129 | ||
130 | if (c == 'E' || c == 'e') { | |
131 | if ((c = *p++) == '-') | |
132 | negexp = -1; | |
133 | else if (c == '+') | |
134 | /* skip it */; | |
135 | else | |
136 | --p; | |
137 | while ((c = *p++) && isdigit(c)) | |
138 | eexp = 10 * eexp + (c-'0'); | |
139 | if (negexp < 0) | |
140 | eexp = -eexp; | |
141 | exp += eexp; | |
142 | } | |
143 | ||
144 | bexp = exp; | |
145 | if (exp < 0) | |
146 | exp = -exp; | |
147 | ||
148 | for (c = 0; exp && c < sizeof exp5 / sizeof exp5[0]; ++c) { | |
149 | if (exp & 1) | |
150 | flexp *= *(double *)&exp5[c]; | |
151 | exp >>= 1; | |
152 | } | |
153 | ||
154 | /* according to ANSI, check for over-/underflow */ | |
155 | if(exp > 0) { | |
156 | if(endp) | |
157 | *endp = (char *)oldp; | |
158 | errno = ERANGE; | |
159 | return neg < 0? -HUGE_VAL: HUGE_VAL; | |
160 | } | |
161 | ||
162 | if (bexp < 0) | |
163 | fl /= flexp; | |
164 | else | |
165 | fl *= flexp; | |
166 | ||
167 | fl = ldexp(fl, bexp); | |
168 | ||
169 | if(endp) | |
170 | *endp = (char *)(p - 1); | |
171 | return neg < 0 ? -fl : fl; | |
172 | } | |
173 | ||
174 | ||
175 | double | |
176 | atof(p) | |
177 | const char *p; | |
178 | { | |
179 | return strtod(p, (char **)NULL); | |
180 | } | |
181 |