comparison lib/strtod.c @ 12421:e8d2c6fc33ad

Use spaces for indentation, not tabs.
author Bruno Haible <bruno@clisp.org>
date Thu, 10 Dec 2009 20:28:30 +0100
parents 48eddbd8edd5
children f7842310a565
comparison
equal deleted inserted replaced
12420:5850b9a81029 12421:e8d2c6fc33ad
36 bool negative = false; 36 bool negative = false;
37 37
38 /* The number so far. */ 38 /* The number so far. */
39 double num; 39 double num;
40 40
41 bool got_dot; /* Found a decimal point. */ 41 bool got_dot; /* Found a decimal point. */
42 bool got_digit; /* Seen any digits. */ 42 bool got_digit; /* Seen any digits. */
43 bool hex = false; /* Look for hex float exponent. */ 43 bool hex = false; /* Look for hex float exponent. */
44 44
45 /* The exponent of the number. */ 45 /* The exponent of the number. */
46 long int exponent; 46 long int exponent;
47 47
48 if (nptr == NULL) 48 if (nptr == NULL)
73 && (c_isxdigit (s[2]) || ('.' == s[2] && c_isxdigit (s[3])))) 73 && (c_isxdigit (s[2]) || ('.' == s[2] && c_isxdigit (s[3]))))
74 { 74 {
75 hex = true; 75 hex = true;
76 s += 2; 76 s += 2;
77 for (;; ++s) 77 for (;; ++s)
78 { 78 {
79 if (c_isxdigit (*s)) 79 if (c_isxdigit (*s))
80 { 80 {
81 got_digit = true; 81 got_digit = true;
82 82
83 /* Make sure that multiplication by 16 will not overflow. */ 83 /* Make sure that multiplication by 16 will not overflow. */
84 if (num > DBL_MAX / 16) 84 if (num > DBL_MAX / 16)
85 /* The value of the digit doesn't matter, since we have already 85 /* The value of the digit doesn't matter, since we have already
86 gotten as many digits as can be represented in a `double'. 86 gotten as many digits as can be represented in a `double'.
87 This doesn't necessarily mean the result will overflow. 87 This doesn't necessarily mean the result will overflow.
88 The exponent may reduce it to within range. 88 The exponent may reduce it to within range.
89 89
90 We just need to record that there was another 90 We just need to record that there was another
91 digit so that we can multiply by 16 later. */ 91 digit so that we can multiply by 16 later. */
92 ++exponent; 92 ++exponent;
93 else 93 else
94 num = ((num * 16.0) 94 num = ((num * 16.0)
95 + (c_tolower (*s) - (c_isdigit (*s) ? '0' : 'a' - 10))); 95 + (c_tolower (*s) - (c_isdigit (*s) ? '0' : 'a' - 10)));
96 96
97 /* Keep track of the number of digits after the decimal point. 97 /* Keep track of the number of digits after the decimal point.
98 If we just divided by 16 here, we would lose precision. */ 98 If we just divided by 16 here, we would lose precision. */
99 if (got_dot) 99 if (got_dot)
100 --exponent; 100 --exponent;
101 } 101 }
102 else if (!got_dot && *s == '.') 102 else if (!got_dot && *s == '.')
103 /* Record that we have found the decimal point. */ 103 /* Record that we have found the decimal point. */
104 got_dot = true; 104 got_dot = true;
105 else 105 else
106 /* Any other character terminates the number. */ 106 /* Any other character terminates the number. */
107 break; 107 break;
108 } 108 }
109 } 109 }
110 110
111 /* Not a hex float. */ 111 /* Not a hex float. */
112 else 112 else
113 { 113 {
114 for (;; ++s) 114 for (;; ++s)
115 { 115 {
116 if (c_isdigit (*s)) 116 if (c_isdigit (*s))
117 { 117 {
118 got_digit = true; 118 got_digit = true;
119 119
120 /* Make sure that multiplication by 10 will not overflow. */ 120 /* Make sure that multiplication by 10 will not overflow. */
121 if (num > DBL_MAX * 0.1) 121 if (num > DBL_MAX * 0.1)
122 /* The value of the digit doesn't matter, since we have already 122 /* The value of the digit doesn't matter, since we have already
123 gotten as many digits as can be represented in a `double'. 123 gotten as many digits as can be represented in a `double'.
124 This doesn't necessarily mean the result will overflow. 124 This doesn't necessarily mean the result will overflow.
125 The exponent may reduce it to within range. 125 The exponent may reduce it to within range.
126 126
127 We just need to record that there was another 127 We just need to record that there was another
128 digit so that we can multiply by 10 later. */ 128 digit so that we can multiply by 10 later. */
129 ++exponent; 129 ++exponent;
130 else 130 else
131 num = (num * 10.0) + (*s - '0'); 131 num = (num * 10.0) + (*s - '0');
132 132
133 /* Keep track of the number of digits after the decimal point. 133 /* Keep track of the number of digits after the decimal point.
134 If we just divided by 10 here, we would lose precision. */ 134 If we just divided by 10 here, we would lose precision. */
135 if (got_dot) 135 if (got_dot)
136 --exponent; 136 --exponent;
137 } 137 }
138 else if (!got_dot && *s == '.') 138 else if (!got_dot && *s == '.')
139 /* Record that we have found the decimal point. */ 139 /* Record that we have found the decimal point. */
140 got_dot = true; 140 got_dot = true;
141 else 141 else
142 /* Any other character terminates the number. */ 142 /* Any other character terminates the number. */
143 break; 143 break;
144 } 144 }
145 } 145 }
146 146
147 if (!got_digit) 147 if (!got_digit)
148 { 148 {
149 /* Check for infinities and NaNs. */ 149 /* Check for infinities and NaNs. */
150 if (c_tolower (*s) == 'i' 150 if (c_tolower (*s) == 'i'
151 && c_tolower (s[1]) == 'n' 151 && c_tolower (s[1]) == 'n'
152 && c_tolower (s[2]) == 'f') 152 && c_tolower (s[2]) == 'f')
153 { 153 {
154 s += 3; 154 s += 3;
155 num = HUGE_VAL; 155 num = HUGE_VAL;
156 if (c_tolower (*s) == 'i' 156 if (c_tolower (*s) == 'i'
157 && c_tolower (s[1]) == 'n' 157 && c_tolower (s[1]) == 'n'
158 && c_tolower (s[2]) == 'i' 158 && c_tolower (s[2]) == 'i'
159 && c_tolower (s[3]) == 't' 159 && c_tolower (s[3]) == 't'
160 && c_tolower (s[4]) == 'y') 160 && c_tolower (s[4]) == 'y')
161 s += 5; 161 s += 5;
162 goto valid; 162 goto valid;
163 } 163 }
164 #ifdef NAN 164 #ifdef NAN
165 else if (c_tolower (*s) == 'n' 165 else if (c_tolower (*s) == 'n'
166 && c_tolower (s[1]) == 'a' 166 && c_tolower (s[1]) == 'a'
167 && c_tolower (s[2]) == 'n') 167 && c_tolower (s[2]) == 'n')
168 { 168 {
169 s += 3; 169 s += 3;
170 num = NAN; 170 num = NAN;
171 /* Since nan(<n-char-sequence>) is implementation-defined, 171 /* Since nan(<n-char-sequence>) is implementation-defined,
172 we define it by ignoring <n-char-sequence>. A nicer 172 we define it by ignoring <n-char-sequence>. A nicer
173 implementation would populate the bits of the NaN 173 implementation would populate the bits of the NaN
174 according to interpreting n-char-sequence as a 174 according to interpreting n-char-sequence as a
175 hexadecimal number, but the result is still a NaN. */ 175 hexadecimal number, but the result is still a NaN. */
176 if (*s == '(') 176 if (*s == '(')
177 { 177 {
178 const unsigned char *p = s + 1; 178 const unsigned char *p = s + 1;
179 while (c_isalnum (*p)) 179 while (c_isalnum (*p))
180 p++; 180 p++;
181 if (*p == ')') 181 if (*p == ')')
182 s = p + 1; 182 s = p + 1;
183 } 183 }
184 goto valid; 184 goto valid;
185 } 185 }
186 #endif 186 #endif
187 goto noconv; 187 goto noconv;
188 } 188 }
189 189
190 if (c_tolower (*s) == (hex ? 'p' : 'e') && !isspace (s[1])) 190 if (c_tolower (*s) == (hex ? 'p' : 'e') && !isspace (s[1]))
196 196
197 errno = 0; 197 errno = 0;
198 ++s; 198 ++s;
199 value = strtol ((char *) s, &end, 10); 199 value = strtol ((char *) s, &end, 10);
200 if (errno == ERANGE && num) 200 if (errno == ERANGE && num)
201 { 201 {
202 /* The exponent overflowed a `long int'. It is probably a safe 202 /* The exponent overflowed a `long int'. It is probably a safe
203 assumption that an exponent that cannot be represented by 203 assumption that an exponent that cannot be represented by
204 a `long int' exceeds the limits of a `double'. */ 204 a `long int' exceeds the limits of a `double'. */
205 if (endptr != NULL) 205 if (endptr != NULL)
206 *endptr = end; 206 *endptr = end;
207 if (value < 0) 207 if (value < 0)
208 goto underflow; 208 goto underflow;
209 else 209 else
210 goto overflow; 210 goto overflow;
211 } 211 }
212 else if (end == (char *) s) 212 else if (end == (char *) s)
213 /* There was no exponent. Reset END to point to 213 /* There was no exponent. Reset END to point to
214 the 'e' or 'E', so *ENDPTR will be set there. */ 214 the 'e' or 'E', so *ENDPTR will be set there. */
215 end = (char *) s - 1; 215 end = (char *) s - 1;
216 errno = save; 216 errno = save;
217 s = (unsigned char *) end; 217 s = (unsigned char *) end;
218 exponent += value; 218 exponent += value;
219 } 219 }
220 220
232 checking for overflow and underflow. */ 232 checking for overflow and underflow. */
233 233
234 if (exponent < 0) 234 if (exponent < 0)
235 { 235 {
236 if (num < DBL_MIN * pow (10.0, (double) -exponent)) 236 if (num < DBL_MIN * pow (10.0, (double) -exponent))
237 goto underflow; 237 goto underflow;
238 } 238 }
239 else if (exponent > 0) 239 else if (exponent > 0)
240 { 240 {
241 if (num > DBL_MAX * pow (10.0, (double) -exponent)) 241 if (num > DBL_MAX * pow (10.0, (double) -exponent))
242 goto overflow; 242 goto overflow;
243 } 243 }
244 244
245 num *= pow (10.0, (double) exponent); 245 num *= pow (10.0, (double) exponent);
246 246
247 valid: 247 valid: