]>
Commit | Line | Data |
---|---|---|
c8042e10 DM |
1 | /* -*- Mode: C; c-file-style: "python" -*- */\r |
2 | \r | |
3 | #include <Python.h>\r | |
4 | #include <locale.h>\r | |
5 | \r | |
6 | /* Case-insensitive string match used for nan and inf detection; t should be\r | |
7 | lower-case. Returns 1 for a successful match, 0 otherwise. */\r | |
8 | \r | |
9 | static int\r | |
10 | case_insensitive_match(const char *s, const char *t)\r | |
11 | {\r | |
12 | while(*t && Py_TOLOWER(*s) == *t) {\r | |
13 | s++;\r | |
14 | t++;\r | |
15 | }\r | |
16 | return *t ? 0 : 1;\r | |
17 | }\r | |
18 | \r | |
19 | /* _Py_parse_inf_or_nan: Attempt to parse a string of the form "nan", "inf" or\r | |
20 | "infinity", with an optional leading sign of "+" or "-". On success,\r | |
21 | return the NaN or Infinity as a double and set *endptr to point just beyond\r | |
22 | the successfully parsed portion of the string. On failure, return -1.0 and\r | |
23 | set *endptr to point to the start of the string. */\r | |
24 | \r | |
25 | double\r | |
26 | _Py_parse_inf_or_nan(const char *p, char **endptr)\r | |
27 | {\r | |
28 | double retval;\r | |
29 | const char *s;\r | |
30 | int negate = 0;\r | |
31 | \r | |
32 | s = p;\r | |
33 | if (*s == '-') {\r | |
34 | negate = 1;\r | |
35 | s++;\r | |
36 | }\r | |
37 | else if (*s == '+') {\r | |
38 | s++;\r | |
39 | }\r | |
40 | if (case_insensitive_match(s, "inf")) {\r | |
41 | s += 3;\r | |
42 | if (case_insensitive_match(s, "inity"))\r | |
43 | s += 5;\r | |
44 | retval = negate ? -Py_HUGE_VAL : Py_HUGE_VAL;\r | |
45 | }\r | |
46 | #ifdef Py_NAN\r | |
47 | else if (case_insensitive_match(s, "nan")) {\r | |
48 | s += 3;\r | |
49 | retval = negate ? -Py_NAN : Py_NAN;\r | |
50 | }\r | |
51 | #endif\r | |
52 | else {\r | |
53 | s = p;\r | |
54 | retval = -1.0;\r | |
55 | }\r | |
56 | *endptr = (char *)s;\r | |
57 | return retval;\r | |
58 | }\r | |
59 | \r | |
60 | /**\r | |
61 | * PyOS_ascii_strtod:\r | |
62 | * @nptr: the string to convert to a numeric value.\r | |
63 | * @endptr: if non-%NULL, it returns the character after\r | |
64 | * the last character used in the conversion.\r | |
65 | *\r | |
66 | * Converts a string to a #gdouble value.\r | |
67 | * This function behaves like the standard strtod() function\r | |
68 | * does in the C locale. It does this without actually\r | |
69 | * changing the current locale, since that would not be\r | |
70 | * thread-safe.\r | |
71 | *\r | |
72 | * This function is typically used when reading configuration\r | |
73 | * files or other non-user input that should be locale independent.\r | |
74 | * To handle input from the user you should normally use the\r | |
75 | * locale-sensitive system strtod() function.\r | |
76 | *\r | |
77 | * If the correct value would cause overflow, plus or minus %HUGE_VAL\r | |
78 | * is returned (according to the sign of the value), and %ERANGE is\r | |
79 | * stored in %errno. If the correct value would cause underflow,\r | |
80 | * zero is returned and %ERANGE is stored in %errno.\r | |
81 | * If memory allocation fails, %ENOMEM is stored in %errno.\r | |
82 | *\r | |
83 | * This function resets %errno before calling strtod() so that\r | |
84 | * you can reliably detect overflow and underflow.\r | |
85 | *\r | |
86 | * Return value: the #gdouble value.\r | |
87 | **/\r | |
88 | \r | |
89 | #ifndef PY_NO_SHORT_FLOAT_REPR\r | |
90 | \r | |
91 | double\r | |
92 | _PyOS_ascii_strtod(const char *nptr, char **endptr)\r | |
93 | {\r | |
94 | double result;\r | |
95 | _Py_SET_53BIT_PRECISION_HEADER;\r | |
96 | \r | |
97 | assert(nptr != NULL);\r | |
98 | /* Set errno to zero, so that we can distinguish zero results\r | |
99 | and underflows */\r | |
100 | errno = 0;\r | |
101 | \r | |
102 | _Py_SET_53BIT_PRECISION_START;\r | |
103 | result = _Py_dg_strtod(nptr, endptr);\r | |
104 | _Py_SET_53BIT_PRECISION_END;\r | |
105 | \r | |
106 | if (*endptr == nptr)\r | |
107 | /* string might represent an inf or nan */\r | |
108 | result = _Py_parse_inf_or_nan(nptr, endptr);\r | |
109 | \r | |
110 | return result;\r | |
111 | \r | |
112 | }\r | |
113 | \r | |
114 | #else\r | |
115 | \r | |
116 | /*\r | |
117 | Use system strtod; since strtod is locale aware, we may\r | |
118 | have to first fix the decimal separator.\r | |
119 | \r | |
120 | Note that unlike _Py_dg_strtod, the system strtod may not always give\r | |
121 | correctly rounded results.\r | |
122 | */\r | |
123 | \r | |
124 | double\r | |
125 | _PyOS_ascii_strtod(const char *nptr, char **endptr)\r | |
126 | {\r | |
127 | char *fail_pos;\r | |
128 | double val = -1.0;\r | |
129 | struct lconv *locale_data;\r | |
130 | const char *decimal_point;\r | |
131 | size_t decimal_point_len;\r | |
132 | const char *p, *decimal_point_pos;\r | |
133 | const char *end = NULL; /* Silence gcc */\r | |
134 | const char *digits_pos = NULL;\r | |
135 | int negate = 0;\r | |
136 | \r | |
137 | assert(nptr != NULL);\r | |
138 | \r | |
139 | fail_pos = NULL;\r | |
140 | \r | |
141 | locale_data = localeconv();\r | |
142 | decimal_point = locale_data->decimal_point;\r | |
143 | decimal_point_len = strlen(decimal_point);\r | |
144 | \r | |
145 | assert(decimal_point_len != 0);\r | |
146 | \r | |
147 | decimal_point_pos = NULL;\r | |
148 | \r | |
149 | /* Parse infinities and nans */\r | |
150 | val = _Py_parse_inf_or_nan(nptr, endptr);\r | |
151 | if (*endptr != nptr)\r | |
152 | return val;\r | |
153 | \r | |
154 | /* Set errno to zero, so that we can distinguish zero results\r | |
155 | and underflows */\r | |
156 | errno = 0;\r | |
157 | \r | |
158 | /* We process the optional sign manually, then pass the remainder to\r | |
159 | the system strtod. This ensures that the result of an underflow\r | |
160 | has the correct sign. (bug #1725) */\r | |
161 | p = nptr;\r | |
162 | /* Process leading sign, if present */\r | |
163 | if (*p == '-') {\r | |
164 | negate = 1;\r | |
165 | p++;\r | |
166 | }\r | |
167 | else if (*p == '+') {\r | |
168 | p++;\r | |
169 | }\r | |
170 | \r | |
171 | /* Some platform strtods accept hex floats; Python shouldn't (at the\r | |
172 | moment), so we check explicitly for strings starting with '0x'. */\r | |
173 | if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X'))\r | |
174 | goto invalid_string;\r | |
175 | \r | |
176 | /* Check that what's left begins with a digit or decimal point */\r | |
177 | if (!Py_ISDIGIT(*p) && *p != '.')\r | |
178 | goto invalid_string;\r | |
179 | \r | |
180 | digits_pos = p;\r | |
181 | if (decimal_point[0] != '.' ||\r | |
182 | decimal_point[1] != 0)\r | |
183 | {\r | |
184 | /* Look for a '.' in the input; if present, it'll need to be\r | |
185 | swapped for the current locale's decimal point before we\r | |
186 | call strtod. On the other hand, if we find the current\r | |
187 | locale's decimal point then the input is invalid. */\r | |
188 | while (Py_ISDIGIT(*p))\r | |
189 | p++;\r | |
190 | \r | |
191 | if (*p == '.')\r | |
192 | {\r | |
193 | decimal_point_pos = p++;\r | |
194 | \r | |
195 | /* locate end of number */\r | |
196 | while (Py_ISDIGIT(*p))\r | |
197 | p++;\r | |
198 | \r | |
199 | if (*p == 'e' || *p == 'E')\r | |
200 | p++;\r | |
201 | if (*p == '+' || *p == '-')\r | |
202 | p++;\r | |
203 | while (Py_ISDIGIT(*p))\r | |
204 | p++;\r | |
205 | end = p;\r | |
206 | }\r | |
207 | else if (strncmp(p, decimal_point, decimal_point_len) == 0)\r | |
208 | /* Python bug #1417699 */\r | |
209 | goto invalid_string;\r | |
210 | /* For the other cases, we need not convert the decimal\r | |
211 | point */\r | |
212 | }\r | |
213 | \r | |
214 | if (decimal_point_pos) {\r | |
215 | char *copy, *c;\r | |
216 | /* Create a copy of the input, with the '.' converted to the\r | |
217 | locale-specific decimal point */\r | |
218 | copy = (char *)PyMem_MALLOC(end - digits_pos +\r | |
219 | 1 + decimal_point_len);\r | |
220 | if (copy == NULL) {\r | |
221 | *endptr = (char *)nptr;\r | |
222 | errno = ENOMEM;\r | |
223 | return val;\r | |
224 | }\r | |
225 | \r | |
226 | c = copy;\r | |
227 | memcpy(c, digits_pos, decimal_point_pos - digits_pos);\r | |
228 | c += decimal_point_pos - digits_pos;\r | |
229 | memcpy(c, decimal_point, decimal_point_len);\r | |
230 | c += decimal_point_len;\r | |
231 | memcpy(c, decimal_point_pos + 1,\r | |
232 | end - (decimal_point_pos + 1));\r | |
233 | c += end - (decimal_point_pos + 1);\r | |
234 | *c = 0;\r | |
235 | \r | |
236 | val = strtod(copy, &fail_pos);\r | |
237 | \r | |
238 | if (fail_pos)\r | |
239 | {\r | |
240 | if (fail_pos > decimal_point_pos)\r | |
241 | fail_pos = (char *)digits_pos +\r | |
242 | (fail_pos - copy) -\r | |
243 | (decimal_point_len - 1);\r | |
244 | else\r | |
245 | fail_pos = (char *)digits_pos +\r | |
246 | (fail_pos - copy);\r | |
247 | }\r | |
248 | \r | |
249 | PyMem_FREE(copy);\r | |
250 | \r | |
251 | }\r | |
252 | else {\r | |
253 | val = strtod(digits_pos, &fail_pos);\r | |
254 | }\r | |
255 | \r | |
256 | if (fail_pos == digits_pos)\r | |
257 | goto invalid_string;\r | |
258 | \r | |
259 | if (negate && fail_pos != nptr)\r | |
260 | val = -val;\r | |
261 | *endptr = fail_pos;\r | |
262 | \r | |
263 | return val;\r | |
264 | \r | |
265 | invalid_string:\r | |
266 | *endptr = (char*)nptr;\r | |
267 | errno = EINVAL;\r | |
268 | return -1.0;\r | |
269 | }\r | |
270 | \r | |
271 | #endif\r | |
272 | \r | |
273 | /* PyOS_ascii_strtod is DEPRECATED in Python 2.7 and 3.1 */\r | |
274 | \r | |
275 | double\r | |
276 | PyOS_ascii_strtod(const char *nptr, char **endptr)\r | |
277 | {\r | |
278 | char *fail_pos;\r | |
279 | const char *p;\r | |
280 | double x;\r | |
281 | \r | |
282 | if (PyErr_WarnEx(PyExc_DeprecationWarning,\r | |
283 | "PyOS_ascii_strtod and PyOS_ascii_atof are "\r | |
284 | "deprecated. Use PyOS_string_to_double "\r | |
285 | "instead.", 1) < 0)\r | |
286 | return -1.0;\r | |
287 | \r | |
288 | /* _PyOS_ascii_strtod already does everything that we want,\r | |
289 | except that it doesn't parse leading whitespace */\r | |
290 | p = nptr;\r | |
291 | while (Py_ISSPACE(*p))\r | |
292 | p++;\r | |
293 | x = _PyOS_ascii_strtod(p, &fail_pos);\r | |
294 | if (fail_pos == p)\r | |
295 | fail_pos = (char *)nptr;\r | |
296 | if (endptr)\r | |
297 | *endptr = (char *)fail_pos;\r | |
298 | return x;\r | |
299 | }\r | |
300 | \r | |
301 | /* PyOS_ascii_strtod is DEPRECATED in Python 2.7 and 3.1 */\r | |
302 | \r | |
303 | double\r | |
304 | PyOS_ascii_atof(const char *nptr)\r | |
305 | {\r | |
306 | return PyOS_ascii_strtod(nptr, NULL);\r | |
307 | }\r | |
308 | \r | |
309 | /* PyOS_string_to_double is the recommended replacement for the deprecated\r | |
310 | PyOS_ascii_strtod and PyOS_ascii_atof functions. It converts a\r | |
311 | null-terminated byte string s (interpreted as a string of ASCII characters)\r | |
312 | to a float. The string should not have leading or trailing whitespace (in\r | |
313 | contrast, PyOS_ascii_strtod allows leading whitespace but not trailing\r | |
314 | whitespace). The conversion is independent of the current locale.\r | |
315 | \r | |
316 | If endptr is NULL, try to convert the whole string. Raise ValueError and\r | |
317 | return -1.0 if the string is not a valid representation of a floating-point\r | |
318 | number.\r | |
319 | \r | |
320 | If endptr is non-NULL, try to convert as much of the string as possible.\r | |
321 | If no initial segment of the string is the valid representation of a\r | |
322 | floating-point number then *endptr is set to point to the beginning of the\r | |
323 | string, -1.0 is returned and again ValueError is raised.\r | |
324 | \r | |
325 | On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine),\r | |
326 | if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python\r | |
327 | exception is raised. Otherwise, overflow_exception should point to\r | |
328 | a Python exception, this exception will be raised, -1.0 will be returned,\r | |
329 | and *endptr will point just past the end of the converted value.\r | |
330 | \r | |
331 | If any other failure occurs (for example lack of memory), -1.0 is returned\r | |
332 | and the appropriate Python exception will have been set.\r | |
333 | */\r | |
334 | \r | |
335 | double\r | |
336 | PyOS_string_to_double(const char *s,\r | |
337 | char **endptr,\r | |
338 | PyObject *overflow_exception)\r | |
339 | {\r | |
340 | double x, result=-1.0;\r | |
341 | char *fail_pos;\r | |
342 | \r | |
343 | errno = 0;\r | |
344 | PyFPE_START_PROTECT("PyOS_string_to_double", return -1.0)\r | |
345 | x = _PyOS_ascii_strtod(s, &fail_pos);\r | |
346 | PyFPE_END_PROTECT(x)\r | |
347 | \r | |
348 | if (errno == ENOMEM) {\r | |
349 | PyErr_NoMemory();\r | |
350 | fail_pos = (char *)s;\r | |
351 | }\r | |
352 | else if (!endptr && (fail_pos == s || *fail_pos != '\0'))\r | |
353 | PyErr_Format(PyExc_ValueError,\r | |
354 | "could not convert string to float: "\r | |
355 | "%.200s", s);\r | |
356 | else if (fail_pos == s)\r | |
357 | PyErr_Format(PyExc_ValueError,\r | |
358 | "could not convert string to float: "\r | |
359 | "%.200s", s);\r | |
360 | else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception)\r | |
361 | PyErr_Format(overflow_exception,\r | |
362 | "value too large to convert to float: "\r | |
363 | "%.200s", s);\r | |
364 | else\r | |
365 | result = x;\r | |
366 | \r | |
367 | if (endptr != NULL)\r | |
368 | *endptr = fail_pos;\r | |
369 | return result;\r | |
370 | }\r | |
371 | \r | |
372 | /* Given a string that may have a decimal point in the current\r | |
373 | locale, change it back to a dot. Since the string cannot get\r | |
374 | longer, no need for a maximum buffer size parameter. */\r | |
375 | Py_LOCAL_INLINE(void)\r | |
376 | change_decimal_from_locale_to_dot(char* buffer)\r | |
377 | {\r | |
378 | struct lconv *locale_data = localeconv();\r | |
379 | const char *decimal_point = locale_data->decimal_point;\r | |
380 | \r | |
381 | if (decimal_point[0] != '.' || decimal_point[1] != 0) {\r | |
382 | size_t decimal_point_len = strlen(decimal_point);\r | |
383 | \r | |
384 | if (*buffer == '+' || *buffer == '-')\r | |
385 | buffer++;\r | |
386 | while (Py_ISDIGIT(*buffer))\r | |
387 | buffer++;\r | |
388 | if (strncmp(buffer, decimal_point, decimal_point_len) == 0) {\r | |
389 | *buffer = '.';\r | |
390 | buffer++;\r | |
391 | if (decimal_point_len > 1) {\r | |
392 | /* buffer needs to get smaller */\r | |
393 | size_t rest_len = strlen(buffer +\r | |
394 | (decimal_point_len - 1));\r | |
395 | memmove(buffer,\r | |
396 | buffer + (decimal_point_len - 1),\r | |
397 | rest_len);\r | |
398 | buffer[rest_len] = 0;\r | |
399 | }\r | |
400 | }\r | |
401 | }\r | |
402 | }\r | |
403 | \r | |
404 | \r | |
405 | /* From the C99 standard, section 7.19.6:\r | |
406 | The exponent always contains at least two digits, and only as many more digits\r | |
407 | as necessary to represent the exponent.\r | |
408 | */\r | |
409 | #define MIN_EXPONENT_DIGITS 2\r | |
410 | \r | |
411 | /* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS\r | |
412 | in length. */\r | |
413 | Py_LOCAL_INLINE(void)\r | |
414 | ensure_minimum_exponent_length(char* buffer, size_t buf_size)\r | |
415 | {\r | |
416 | char *p = strpbrk(buffer, "eE");\r | |
417 | if (p && (*(p + 1) == '-' || *(p + 1) == '+')) {\r | |
418 | char *start = p + 2;\r | |
419 | int exponent_digit_cnt = 0;\r | |
420 | int leading_zero_cnt = 0;\r | |
421 | int in_leading_zeros = 1;\r | |
422 | int significant_digit_cnt;\r | |
423 | \r | |
424 | /* Skip over the exponent and the sign. */\r | |
425 | p += 2;\r | |
426 | \r | |
427 | /* Find the end of the exponent, keeping track of leading\r | |
428 | zeros. */\r | |
429 | while (*p && Py_ISDIGIT(*p)) {\r | |
430 | if (in_leading_zeros && *p == '0')\r | |
431 | ++leading_zero_cnt;\r | |
432 | if (*p != '0')\r | |
433 | in_leading_zeros = 0;\r | |
434 | ++p;\r | |
435 | ++exponent_digit_cnt;\r | |
436 | }\r | |
437 | \r | |
438 | significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt;\r | |
439 | if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) {\r | |
440 | /* If there are 2 exactly digits, we're done,\r | |
441 | regardless of what they contain */\r | |
442 | }\r | |
443 | else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) {\r | |
444 | int extra_zeros_cnt;\r | |
445 | \r | |
446 | /* There are more than 2 digits in the exponent. See\r | |
447 | if we can delete some of the leading zeros */\r | |
448 | if (significant_digit_cnt < MIN_EXPONENT_DIGITS)\r | |
449 | significant_digit_cnt = MIN_EXPONENT_DIGITS;\r | |
450 | extra_zeros_cnt = exponent_digit_cnt -\r | |
451 | significant_digit_cnt;\r | |
452 | \r | |
453 | /* Delete extra_zeros_cnt worth of characters from the\r | |
454 | front of the exponent */\r | |
455 | assert(extra_zeros_cnt >= 0);\r | |
456 | \r | |
457 | /* Add one to significant_digit_cnt to copy the\r | |
458 | trailing 0 byte, thus setting the length */\r | |
459 | memmove(start,\r | |
460 | start + extra_zeros_cnt,\r | |
461 | significant_digit_cnt + 1);\r | |
462 | }\r | |
463 | else {\r | |
464 | /* If there are fewer than 2 digits, add zeros\r | |
465 | until there are 2, if there's enough room */\r | |
466 | int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt;\r | |
467 | if (start + zeros + exponent_digit_cnt + 1\r | |
468 | < buffer + buf_size) {\r | |
469 | memmove(start + zeros, start,\r | |
470 | exponent_digit_cnt + 1);\r | |
471 | memset(start, '0', zeros);\r | |
472 | }\r | |
473 | }\r | |
474 | }\r | |
475 | }\r | |
476 | \r | |
477 | /* Remove trailing zeros after the decimal point from a numeric string; also\r | |
478 | remove the decimal point if all digits following it are zero. The numeric\r | |
479 | string must end in '\0', and should not have any leading or trailing\r | |
480 | whitespace. Assumes that the decimal point is '.'. */\r | |
481 | Py_LOCAL_INLINE(void)\r | |
482 | remove_trailing_zeros(char *buffer)\r | |
483 | {\r | |
484 | char *old_fraction_end, *new_fraction_end, *end, *p;\r | |
485 | \r | |
486 | p = buffer;\r | |
487 | if (*p == '-' || *p == '+')\r | |
488 | /* Skip leading sign, if present */\r | |
489 | ++p;\r | |
490 | while (Py_ISDIGIT(*p))\r | |
491 | ++p;\r | |
492 | \r | |
493 | /* if there's no decimal point there's nothing to do */\r | |
494 | if (*p++ != '.')\r | |
495 | return;\r | |
496 | \r | |
497 | /* scan any digits after the point */\r | |
498 | while (Py_ISDIGIT(*p))\r | |
499 | ++p;\r | |
500 | old_fraction_end = p;\r | |
501 | \r | |
502 | /* scan up to ending '\0' */\r | |
503 | while (*p != '\0')\r | |
504 | p++;\r | |
505 | /* +1 to make sure that we move the null byte as well */\r | |
506 | end = p+1;\r | |
507 | \r | |
508 | /* scan back from fraction_end, looking for removable zeros */\r | |
509 | p = old_fraction_end;\r | |
510 | while (*(p-1) == '0')\r | |
511 | --p;\r | |
512 | /* and remove point if we've got that far */\r | |
513 | if (*(p-1) == '.')\r | |
514 | --p;\r | |
515 | new_fraction_end = p;\r | |
516 | \r | |
517 | memmove(new_fraction_end, old_fraction_end, end-old_fraction_end);\r | |
518 | }\r | |
519 | \r | |
520 | /* Ensure that buffer has a decimal point in it. The decimal point will not\r | |
521 | be in the current locale, it will always be '.'. Don't add a decimal point\r | |
522 | if an exponent is present. Also, convert to exponential notation where\r | |
523 | adding a '.0' would produce too many significant digits (see issue 5864).\r | |
524 | \r | |
525 | Returns a pointer to the fixed buffer, or NULL on failure.\r | |
526 | */\r | |
527 | Py_LOCAL_INLINE(char *)\r | |
528 | ensure_decimal_point(char* buffer, size_t buf_size, int precision)\r | |
529 | {\r | |
530 | int digit_count, insert_count = 0, convert_to_exp = 0;\r | |
531 | char *chars_to_insert, *digits_start;\r | |
532 | \r | |
533 | /* search for the first non-digit character */\r | |
534 | char *p = buffer;\r | |
535 | if (*p == '-' || *p == '+')\r | |
536 | /* Skip leading sign, if present. I think this could only\r | |
537 | ever be '-', but it can't hurt to check for both. */\r | |
538 | ++p;\r | |
539 | digits_start = p;\r | |
540 | while (*p && Py_ISDIGIT(*p))\r | |
541 | ++p;\r | |
542 | digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int);\r | |
543 | \r | |
544 | if (*p == '.') {\r | |
545 | if (Py_ISDIGIT(*(p+1))) {\r | |
546 | /* Nothing to do, we already have a decimal\r | |
547 | point and a digit after it */\r | |
548 | }\r | |
549 | else {\r | |
550 | /* We have a decimal point, but no following\r | |
551 | digit. Insert a zero after the decimal. */\r | |
552 | /* can't ever get here via PyOS_double_to_string */\r | |
553 | assert(precision == -1);\r | |
554 | ++p;\r | |
555 | chars_to_insert = "0";\r | |
556 | insert_count = 1;\r | |
557 | }\r | |
558 | }\r | |
559 | else if (!(*p == 'e' || *p == 'E')) {\r | |
560 | /* Don't add ".0" if we have an exponent. */\r | |
561 | if (digit_count == precision) {\r | |
562 | /* issue 5864: don't add a trailing .0 in the case\r | |
563 | where the '%g'-formatted result already has as many\r | |
564 | significant digits as were requested. Switch to\r | |
565 | exponential notation instead. */\r | |
566 | convert_to_exp = 1;\r | |
567 | /* no exponent, no point, and we shouldn't land here\r | |
568 | for infs and nans, so we must be at the end of the\r | |
569 | string. */\r | |
570 | assert(*p == '\0');\r | |
571 | }\r | |
572 | else {\r | |
573 | assert(precision == -1 || digit_count < precision);\r | |
574 | chars_to_insert = ".0";\r | |
575 | insert_count = 2;\r | |
576 | }\r | |
577 | }\r | |
578 | if (insert_count) {\r | |
579 | size_t buf_len = strlen(buffer);\r | |
580 | if (buf_len + insert_count + 1 >= buf_size) {\r | |
581 | /* If there is not enough room in the buffer\r | |
582 | for the additional text, just skip it. It's\r | |
583 | not worth generating an error over. */\r | |
584 | }\r | |
585 | else {\r | |
586 | memmove(p + insert_count, p,\r | |
587 | buffer + strlen(buffer) - p + 1);\r | |
588 | memcpy(p, chars_to_insert, insert_count);\r | |
589 | }\r | |
590 | }\r | |
591 | if (convert_to_exp) {\r | |
592 | int written;\r | |
593 | size_t buf_avail;\r | |
594 | p = digits_start;\r | |
595 | /* insert decimal point */\r | |
596 | assert(digit_count >= 1);\r | |
597 | memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */\r | |
598 | p[1] = '.';\r | |
599 | p += digit_count+1;\r | |
600 | assert(p <= buf_size+buffer);\r | |
601 | buf_avail = buf_size+buffer-p;\r | |
602 | if (buf_avail == 0)\r | |
603 | return NULL;\r | |
604 | /* Add exponent. It's okay to use lower case 'e': we only\r | |
605 | arrive here as a result of using the empty format code or\r | |
606 | repr/str builtins and those never want an upper case 'E' */\r | |
607 | written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1);\r | |
608 | if (!(0 <= written &&\r | |
609 | written < Py_SAFE_DOWNCAST(buf_avail, size_t, int)))\r | |
610 | /* output truncated, or something else bad happened */\r | |
611 | return NULL;\r | |
612 | remove_trailing_zeros(buffer);\r | |
613 | }\r | |
614 | return buffer;\r | |
615 | }\r | |
616 | \r | |
617 | /* see FORMATBUFLEN in unicodeobject.c */\r | |
618 | #define FLOAT_FORMATBUFLEN 120\r | |
619 | \r | |
620 | /**\r | |
621 | * PyOS_ascii_formatd:\r | |
622 | * @buffer: A buffer to place the resulting string in\r | |
623 | * @buf_size: The length of the buffer.\r | |
624 | * @format: The printf()-style format to use for the\r | |
625 | * code to use for converting.\r | |
626 | * @d: The #gdouble to convert\r | |
627 | *\r | |
628 | * Converts a #gdouble to a string, using the '.' as\r | |
629 | * decimal point. To format the number you pass in\r | |
630 | * a printf()-style format string. Allowed conversion\r | |
631 | * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'.\r | |
632 | *\r | |
633 | * 'Z' is the same as 'g', except it always has a decimal and\r | |
634 | * at least one digit after the decimal.\r | |
635 | *\r | |
636 | * Return value: The pointer to the buffer with the converted string.\r | |
637 | * On failure returns NULL but does not set any Python exception.\r | |
638 | **/\r | |
639 | char *\r | |
640 | _PyOS_ascii_formatd(char *buffer,\r | |
641 | size_t buf_size,\r | |
642 | const char *format,\r | |
643 | double d,\r | |
644 | int precision)\r | |
645 | {\r | |
646 | char format_char;\r | |
647 | size_t format_len = strlen(format);\r | |
648 | \r | |
649 | /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but\r | |
650 | also with at least one character past the decimal. */\r | |
651 | char tmp_format[FLOAT_FORMATBUFLEN];\r | |
652 | \r | |
653 | /* The last character in the format string must be the format char */\r | |
654 | format_char = format[format_len - 1];\r | |
655 | \r | |
656 | if (format[0] != '%')\r | |
657 | return NULL;\r | |
658 | \r | |
659 | /* I'm not sure why this test is here. It's ensuring that the format\r | |
660 | string after the first character doesn't have a single quote, a\r | |
661 | lowercase l, or a percent. This is the reverse of the commented-out\r | |
662 | test about 10 lines ago. */\r | |
663 | if (strpbrk(format + 1, "'l%"))\r | |
664 | return NULL;\r | |
665 | \r | |
666 | /* Also curious about this function is that it accepts format strings\r | |
667 | like "%xg", which are invalid for floats. In general, the\r | |
668 | interface to this function is not very good, but changing it is\r | |
669 | difficult because it's a public API. */\r | |
670 | \r | |
671 | if (!(format_char == 'e' || format_char == 'E' ||\r | |
672 | format_char == 'f' || format_char == 'F' ||\r | |
673 | format_char == 'g' || format_char == 'G' ||\r | |
674 | format_char == 'Z'))\r | |
675 | return NULL;\r | |
676 | \r | |
677 | /* Map 'Z' format_char to 'g', by copying the format string and\r | |
678 | replacing the final char with a 'g' */\r | |
679 | if (format_char == 'Z') {\r | |
680 | if (format_len + 1 >= sizeof(tmp_format)) {\r | |
681 | /* The format won't fit in our copy. Error out. In\r | |
682 | practice, this will never happen and will be\r | |
683 | detected by returning NULL */\r | |
684 | return NULL;\r | |
685 | }\r | |
686 | strcpy(tmp_format, format);\r | |
687 | tmp_format[format_len - 1] = 'g';\r | |
688 | format = tmp_format;\r | |
689 | }\r | |
690 | \r | |
691 | \r | |
692 | /* Have PyOS_snprintf do the hard work */\r | |
693 | PyOS_snprintf(buffer, buf_size, format, d);\r | |
694 | \r | |
695 | /* Do various fixups on the return string */\r | |
696 | \r | |
697 | /* Get the current locale, and find the decimal point string.\r | |
698 | Convert that string back to a dot. */\r | |
699 | change_decimal_from_locale_to_dot(buffer);\r | |
700 | \r | |
701 | /* If an exponent exists, ensure that the exponent is at least\r | |
702 | MIN_EXPONENT_DIGITS digits, providing the buffer is large enough\r | |
703 | for the extra zeros. Also, if there are more than\r | |
704 | MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get\r | |
705 | back to MIN_EXPONENT_DIGITS */\r | |
706 | ensure_minimum_exponent_length(buffer, buf_size);\r | |
707 | \r | |
708 | /* If format_char is 'Z', make sure we have at least one character\r | |
709 | after the decimal point (and make sure we have a decimal point);\r | |
710 | also switch to exponential notation in some edge cases where the\r | |
711 | extra character would produce more significant digits that we\r | |
712 | really want. */\r | |
713 | if (format_char == 'Z')\r | |
714 | buffer = ensure_decimal_point(buffer, buf_size, precision);\r | |
715 | \r | |
716 | return buffer;\r | |
717 | }\r | |
718 | \r | |
719 | char *\r | |
720 | PyOS_ascii_formatd(char *buffer,\r | |
721 | size_t buf_size,\r | |
722 | const char *format,\r | |
723 | double d)\r | |
724 | {\r | |
725 | if (PyErr_WarnEx(PyExc_DeprecationWarning,\r | |
726 | "PyOS_ascii_formatd is deprecated, "\r | |
727 | "use PyOS_double_to_string instead", 1) < 0)\r | |
728 | return NULL;\r | |
729 | \r | |
730 | return _PyOS_ascii_formatd(buffer, buf_size, format, d, -1);\r | |
731 | }\r | |
732 | \r | |
733 | #ifdef PY_NO_SHORT_FLOAT_REPR\r | |
734 | \r | |
735 | /* The fallback code to use if _Py_dg_dtoa is not available. */\r | |
736 | \r | |
737 | PyAPI_FUNC(char *) PyOS_double_to_string(double val,\r | |
738 | char format_code,\r | |
739 | int precision,\r | |
740 | int flags,\r | |
741 | int *type)\r | |
742 | {\r | |
743 | char format[32];\r | |
744 | Py_ssize_t bufsize;\r | |
745 | char *buf;\r | |
746 | int t, exp;\r | |
747 | int upper = 0;\r | |
748 | \r | |
749 | /* Validate format_code, and map upper and lower case */\r | |
750 | switch (format_code) {\r | |
751 | case 'e': /* exponent */\r | |
752 | case 'f': /* fixed */\r | |
753 | case 'g': /* general */\r | |
754 | break;\r | |
755 | case 'E':\r | |
756 | upper = 1;\r | |
757 | format_code = 'e';\r | |
758 | break;\r | |
759 | case 'F':\r | |
760 | upper = 1;\r | |
761 | format_code = 'f';\r | |
762 | break;\r | |
763 | case 'G':\r | |
764 | upper = 1;\r | |
765 | format_code = 'g';\r | |
766 | break;\r | |
767 | case 'r': /* repr format */\r | |
768 | /* Supplied precision is unused, must be 0. */\r | |
769 | if (precision != 0) {\r | |
770 | PyErr_BadInternalCall();\r | |
771 | return NULL;\r | |
772 | }\r | |
773 | /* The repr() precision (17 significant decimal digits) is the\r | |
774 | minimal number that is guaranteed to have enough precision\r | |
775 | so that if the number is read back in the exact same binary\r | |
776 | value is recreated. This is true for IEEE floating point\r | |
777 | by design, and also happens to work for all other modern\r | |
778 | hardware. */\r | |
779 | precision = 17;\r | |
780 | format_code = 'g';\r | |
781 | break;\r | |
782 | default:\r | |
783 | PyErr_BadInternalCall();\r | |
784 | return NULL;\r | |
785 | }\r | |
786 | \r | |
787 | /* Here's a quick-and-dirty calculation to figure out how big a buffer\r | |
788 | we need. In general, for a finite float we need:\r | |
789 | \r | |
790 | 1 byte for each digit of the decimal significand, and\r | |
791 | \r | |
792 | 1 for a possible sign\r | |
793 | 1 for a possible decimal point\r | |
794 | 2 for a possible [eE][+-]\r | |
795 | 1 for each digit of the exponent; if we allow 19 digits\r | |
796 | total then we're safe up to exponents of 2**63.\r | |
797 | 1 for the trailing nul byte\r | |
798 | \r | |
799 | This gives a total of 24 + the number of digits in the significand,\r | |
800 | and the number of digits in the significand is:\r | |
801 | \r | |
802 | for 'g' format: at most precision, except possibly\r | |
803 | when precision == 0, when it's 1.\r | |
804 | for 'e' format: precision+1\r | |
805 | for 'f' format: precision digits after the point, at least 1\r | |
806 | before. To figure out how many digits appear before the point\r | |
807 | we have to examine the size of the number. If fabs(val) < 1.0\r | |
808 | then there will be only one digit before the point. If\r | |
809 | fabs(val) >= 1.0, then there are at most\r | |
810 | \r | |
811 | 1+floor(log10(ceiling(fabs(val))))\r | |
812 | \r | |
813 | digits before the point (where the 'ceiling' allows for the\r | |
814 | possibility that the rounding rounds the integer part of val\r | |
815 | up). A safe upper bound for the above quantity is\r | |
816 | 1+floor(exp/3), where exp is the unique integer such that 0.5\r | |
817 | <= fabs(val)/2**exp < 1.0. This exp can be obtained from\r | |
818 | frexp.\r | |
819 | \r | |
820 | So we allow room for precision+1 digits for all formats, plus an\r | |
821 | extra floor(exp/3) digits for 'f' format.\r | |
822 | \r | |
823 | */\r | |
824 | \r | |
825 | if (Py_IS_NAN(val) || Py_IS_INFINITY(val))\r | |
826 | /* 3 for 'inf'/'nan', 1 for sign, 1 for '\0' */\r | |
827 | bufsize = 5;\r | |
828 | else {\r | |
829 | bufsize = 25 + precision;\r | |
830 | if (format_code == 'f' && fabs(val) >= 1.0) {\r | |
831 | frexp(val, &exp);\r | |
832 | bufsize += exp/3;\r | |
833 | }\r | |
834 | }\r | |
835 | \r | |
836 | buf = PyMem_Malloc(bufsize);\r | |
837 | if (buf == NULL) {\r | |
838 | PyErr_NoMemory();\r | |
839 | return NULL;\r | |
840 | }\r | |
841 | \r | |
842 | /* Handle nan and inf. */\r | |
843 | if (Py_IS_NAN(val)) {\r | |
844 | strcpy(buf, "nan");\r | |
845 | t = Py_DTST_NAN;\r | |
846 | } else if (Py_IS_INFINITY(val)) {\r | |
847 | if (copysign(1., val) == 1.)\r | |
848 | strcpy(buf, "inf");\r | |
849 | else\r | |
850 | strcpy(buf, "-inf");\r | |
851 | t = Py_DTST_INFINITE;\r | |
852 | } else {\r | |
853 | t = Py_DTST_FINITE;\r | |
854 | if (flags & Py_DTSF_ADD_DOT_0)\r | |
855 | format_code = 'Z';\r | |
856 | \r | |
857 | PyOS_snprintf(format, sizeof(format), "%%%s.%i%c",\r | |
858 | (flags & Py_DTSF_ALT ? "#" : ""), precision,\r | |
859 | format_code);\r | |
860 | _PyOS_ascii_formatd(buf, bufsize, format, val, precision);\r | |
861 | }\r | |
862 | \r | |
863 | /* Add sign when requested. It's convenient (esp. when formatting\r | |
864 | complex numbers) to include a sign even for inf and nan. */\r | |
865 | if (flags & Py_DTSF_SIGN && buf[0] != '-') {\r | |
866 | size_t len = strlen(buf);\r | |
867 | /* the bufsize calculations above should ensure that we've got\r | |
868 | space to add a sign */\r | |
869 | assert((size_t)bufsize >= len+2);\r | |
870 | memmove(buf+1, buf, len+1);\r | |
871 | buf[0] = '+';\r | |
872 | }\r | |
873 | if (upper) {\r | |
874 | /* Convert to upper case. */\r | |
875 | char *p1;\r | |
876 | for (p1 = buf; *p1; p1++)\r | |
877 | *p1 = Py_TOUPPER(*p1);\r | |
878 | }\r | |
879 | \r | |
880 | if (type)\r | |
881 | *type = t;\r | |
882 | return buf;\r | |
883 | }\r | |
884 | \r | |
885 | #else\r | |
886 | \r | |
887 | /* _Py_dg_dtoa is available. */\r | |
888 | \r | |
889 | /* I'm using a lookup table here so that I don't have to invent a non-locale\r | |
890 | specific way to convert to uppercase */\r | |
891 | #define OFS_INF 0\r | |
892 | #define OFS_NAN 1\r | |
893 | #define OFS_E 2\r | |
894 | \r | |
895 | /* The lengths of these are known to the code below, so don't change them */\r | |
896 | static char *lc_float_strings[] = {\r | |
897 | "inf",\r | |
898 | "nan",\r | |
899 | "e",\r | |
900 | };\r | |
901 | static char *uc_float_strings[] = {\r | |
902 | "INF",\r | |
903 | "NAN",\r | |
904 | "E",\r | |
905 | };\r | |
906 | \r | |
907 | \r | |
908 | /* Convert a double d to a string, and return a PyMem_Malloc'd block of\r | |
909 | memory contain the resulting string.\r | |
910 | \r | |
911 | Arguments:\r | |
912 | d is the double to be converted\r | |
913 | format_code is one of 'e', 'f', 'g', 'r'. 'e', 'f' and 'g'\r | |
914 | correspond to '%e', '%f' and '%g'; 'r' corresponds to repr.\r | |
915 | mode is one of '0', '2' or '3', and is completely determined by\r | |
916 | format_code: 'e' and 'g' use mode 2; 'f' mode 3, 'r' mode 0.\r | |
917 | precision is the desired precision\r | |
918 | always_add_sign is nonzero if a '+' sign should be included for positive\r | |
919 | numbers\r | |
920 | add_dot_0_if_integer is nonzero if integers in non-exponential form\r | |
921 | should have ".0" added. Only applies to format codes 'r' and 'g'.\r | |
922 | use_alt_formatting is nonzero if alternative formatting should be\r | |
923 | used. Only applies to format codes 'e', 'f' and 'g'. For code 'g',\r | |
924 | at most one of use_alt_formatting and add_dot_0_if_integer should\r | |
925 | be nonzero.\r | |
926 | type, if non-NULL, will be set to one of these constants to identify\r | |
927 | the type of the 'd' argument:\r | |
928 | Py_DTST_FINITE\r | |
929 | Py_DTST_INFINITE\r | |
930 | Py_DTST_NAN\r | |
931 | \r | |
932 | Returns a PyMem_Malloc'd block of memory containing the resulting string,\r | |
933 | or NULL on error. If NULL is returned, the Python error has been set.\r | |
934 | */\r | |
935 | \r | |
936 | static char *\r | |
937 | format_float_short(double d, char format_code,\r | |
938 | int mode, Py_ssize_t precision,\r | |
939 | int always_add_sign, int add_dot_0_if_integer,\r | |
940 | int use_alt_formatting, char **float_strings, int *type)\r | |
941 | {\r | |
942 | char *buf = NULL;\r | |
943 | char *p = NULL;\r | |
944 | Py_ssize_t bufsize = 0;\r | |
945 | char *digits, *digits_end;\r | |
946 | int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0;\r | |
947 | Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end;\r | |
948 | _Py_SET_53BIT_PRECISION_HEADER;\r | |
949 | \r | |
950 | /* _Py_dg_dtoa returns a digit string (no decimal point or exponent).\r | |
951 | Must be matched by a call to _Py_dg_freedtoa. */\r | |
952 | _Py_SET_53BIT_PRECISION_START;\r | |
953 | digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign,\r | |
954 | &digits_end);\r | |
955 | _Py_SET_53BIT_PRECISION_END;\r | |
956 | \r | |
957 | decpt = (Py_ssize_t)decpt_as_int;\r | |
958 | if (digits == NULL) {\r | |
959 | /* The only failure mode is no memory. */\r | |
960 | PyErr_NoMemory();\r | |
961 | goto exit;\r | |
962 | }\r | |
963 | assert(digits_end != NULL && digits_end >= digits);\r | |
964 | digits_len = digits_end - digits;\r | |
965 | \r | |
966 | if (digits_len && !Py_ISDIGIT(digits[0])) {\r | |
967 | /* Infinities and nans here; adapt Gay's output,\r | |
968 | so convert Infinity to inf and NaN to nan, and\r | |
969 | ignore sign of nan. Then return. */\r | |
970 | \r | |
971 | /* ignore the actual sign of a nan */\r | |
972 | if (digits[0] == 'n' || digits[0] == 'N')\r | |
973 | sign = 0;\r | |
974 | \r | |
975 | /* We only need 5 bytes to hold the result "+inf\0" . */\r | |
976 | bufsize = 5; /* Used later in an assert. */\r | |
977 | buf = (char *)PyMem_Malloc(bufsize);\r | |
978 | if (buf == NULL) {\r | |
979 | PyErr_NoMemory();\r | |
980 | goto exit;\r | |
981 | }\r | |
982 | p = buf;\r | |
983 | \r | |
984 | if (sign == 1) {\r | |
985 | *p++ = '-';\r | |
986 | }\r | |
987 | else if (always_add_sign) {\r | |
988 | *p++ = '+';\r | |
989 | }\r | |
990 | if (digits[0] == 'i' || digits[0] == 'I') {\r | |
991 | strncpy(p, float_strings[OFS_INF], 3);\r | |
992 | p += 3;\r | |
993 | \r | |
994 | if (type)\r | |
995 | *type = Py_DTST_INFINITE;\r | |
996 | }\r | |
997 | else if (digits[0] == 'n' || digits[0] == 'N') {\r | |
998 | strncpy(p, float_strings[OFS_NAN], 3);\r | |
999 | p += 3;\r | |
1000 | \r | |
1001 | if (type)\r | |
1002 | *type = Py_DTST_NAN;\r | |
1003 | }\r | |
1004 | else {\r | |
1005 | /* shouldn't get here: Gay's code should always return\r | |
1006 | something starting with a digit, an 'I', or 'N' */\r | |
1007 | strncpy(p, "ERR", 3);\r | |
1008 | p += 3;\r | |
1009 | assert(0);\r | |
1010 | }\r | |
1011 | goto exit;\r | |
1012 | }\r | |
1013 | \r | |
1014 | /* The result must be finite (not inf or nan). */\r | |
1015 | if (type)\r | |
1016 | *type = Py_DTST_FINITE;\r | |
1017 | \r | |
1018 | \r | |
1019 | /* We got digits back, format them. We may need to pad 'digits'\r | |
1020 | either on the left or right (or both) with extra zeros, so in\r | |
1021 | general the resulting string has the form\r | |
1022 | \r | |
1023 | [<sign>]<zeros><digits><zeros>[<exponent>]\r | |
1024 | \r | |
1025 | where either of the <zeros> pieces could be empty, and there's a\r | |
1026 | decimal point that could appear either in <digits> or in the\r | |
1027 | leading or trailing <zeros>.\r | |
1028 | \r | |
1029 | Imagine an infinite 'virtual' string vdigits, consisting of the\r | |
1030 | string 'digits' (starting at index 0) padded on both the left and\r | |
1031 | right with infinite strings of zeros. We want to output a slice\r | |
1032 | \r | |
1033 | vdigits[vdigits_start : vdigits_end]\r | |
1034 | \r | |
1035 | of this virtual string. Thus if vdigits_start < 0 then we'll end\r | |
1036 | up producing some leading zeros; if vdigits_end > digits_len there\r | |
1037 | will be trailing zeros in the output. The next section of code\r | |
1038 | determines whether to use an exponent or not, figures out the\r | |
1039 | position 'decpt' of the decimal point, and computes 'vdigits_start'\r | |
1040 | and 'vdigits_end'. */\r | |
1041 | vdigits_end = digits_len;\r | |
1042 | switch (format_code) {\r | |
1043 | case 'e':\r | |
1044 | use_exp = 1;\r | |
1045 | vdigits_end = precision;\r | |
1046 | break;\r | |
1047 | case 'f':\r | |
1048 | vdigits_end = decpt + precision;\r | |
1049 | break;\r | |
1050 | case 'g':\r | |
1051 | if (decpt <= -4 || decpt >\r | |
1052 | (add_dot_0_if_integer ? precision-1 : precision))\r | |
1053 | use_exp = 1;\r | |
1054 | if (use_alt_formatting)\r | |
1055 | vdigits_end = precision;\r | |
1056 | break;\r | |
1057 | case 'r':\r | |
1058 | /* convert to exponential format at 1e16. We used to convert\r | |
1059 | at 1e17, but that gives odd-looking results for some values\r | |
1060 | when a 16-digit 'shortest' repr is padded with bogus zeros.\r | |
1061 | For example, repr(2e16+8) would give 20000000000000010.0;\r | |
1062 | the true value is 20000000000000008.0. */\r | |
1063 | if (decpt <= -4 || decpt > 16)\r | |
1064 | use_exp = 1;\r | |
1065 | break;\r | |
1066 | default:\r | |
1067 | PyErr_BadInternalCall();\r | |
1068 | goto exit;\r | |
1069 | }\r | |
1070 | \r | |
1071 | /* if using an exponent, reset decimal point position to 1 and adjust\r | |
1072 | exponent accordingly.*/\r | |
1073 | if (use_exp) {\r | |
1074 | exp = decpt - 1;\r | |
1075 | decpt = 1;\r | |
1076 | }\r | |
1077 | /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start <\r | |
1078 | decpt < vdigits_end if add_dot_0_if_integer and no exponent */\r | |
1079 | vdigits_start = decpt <= 0 ? decpt-1 : 0;\r | |
1080 | if (!use_exp && add_dot_0_if_integer)\r | |
1081 | vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1;\r | |
1082 | else\r | |
1083 | vdigits_end = vdigits_end > decpt ? vdigits_end : decpt;\r | |
1084 | \r | |
1085 | /* double check inequalities */\r | |
1086 | assert(vdigits_start <= 0 &&\r | |
1087 | 0 <= digits_len &&\r | |
1088 | digits_len <= vdigits_end);\r | |
1089 | /* decimal point should be in (vdigits_start, vdigits_end] */\r | |
1090 | assert(vdigits_start < decpt && decpt <= vdigits_end);\r | |
1091 | \r | |
1092 | /* Compute an upper bound how much memory we need. This might be a few\r | |
1093 | chars too long, but no big deal. */\r | |
1094 | bufsize =\r | |
1095 | /* sign, decimal point and trailing 0 byte */\r | |
1096 | 3 +\r | |
1097 | \r | |
1098 | /* total digit count (including zero padding on both sides) */\r | |
1099 | (vdigits_end - vdigits_start) +\r | |
1100 | \r | |
1101 | /* exponent "e+100", max 3 numerical digits */\r | |
1102 | (use_exp ? 5 : 0);\r | |
1103 | \r | |
1104 | /* Now allocate the memory and initialize p to point to the start of\r | |
1105 | it. */\r | |
1106 | buf = (char *)PyMem_Malloc(bufsize);\r | |
1107 | if (buf == NULL) {\r | |
1108 | PyErr_NoMemory();\r | |
1109 | goto exit;\r | |
1110 | }\r | |
1111 | p = buf;\r | |
1112 | \r | |
1113 | /* Add a negative sign if negative, and a plus sign if non-negative\r | |
1114 | and always_add_sign is true. */\r | |
1115 | if (sign == 1)\r | |
1116 | *p++ = '-';\r | |
1117 | else if (always_add_sign)\r | |
1118 | *p++ = '+';\r | |
1119 | \r | |
1120 | /* note that exactly one of the three 'if' conditions is true,\r | |
1121 | so we include exactly one decimal point */\r | |
1122 | /* Zero padding on left of digit string */\r | |
1123 | if (decpt <= 0) {\r | |
1124 | memset(p, '0', decpt-vdigits_start);\r | |
1125 | p += decpt - vdigits_start;\r | |
1126 | *p++ = '.';\r | |
1127 | memset(p, '0', 0-decpt);\r | |
1128 | p += 0-decpt;\r | |
1129 | }\r | |
1130 | else {\r | |
1131 | memset(p, '0', 0-vdigits_start);\r | |
1132 | p += 0 - vdigits_start;\r | |
1133 | }\r | |
1134 | \r | |
1135 | /* Digits, with included decimal point */\r | |
1136 | if (0 < decpt && decpt <= digits_len) {\r | |
1137 | strncpy(p, digits, decpt-0);\r | |
1138 | p += decpt-0;\r | |
1139 | *p++ = '.';\r | |
1140 | strncpy(p, digits+decpt, digits_len-decpt);\r | |
1141 | p += digits_len-decpt;\r | |
1142 | }\r | |
1143 | else {\r | |
1144 | strncpy(p, digits, digits_len);\r | |
1145 | p += digits_len;\r | |
1146 | }\r | |
1147 | \r | |
1148 | /* And zeros on the right */\r | |
1149 | if (digits_len < decpt) {\r | |
1150 | memset(p, '0', decpt-digits_len);\r | |
1151 | p += decpt-digits_len;\r | |
1152 | *p++ = '.';\r | |
1153 | memset(p, '0', vdigits_end-decpt);\r | |
1154 | p += vdigits_end-decpt;\r | |
1155 | }\r | |
1156 | else {\r | |
1157 | memset(p, '0', vdigits_end-digits_len);\r | |
1158 | p += vdigits_end-digits_len;\r | |
1159 | }\r | |
1160 | \r | |
1161 | /* Delete a trailing decimal pt unless using alternative formatting. */\r | |
1162 | if (p[-1] == '.' && !use_alt_formatting)\r | |
1163 | p--;\r | |
1164 | \r | |
1165 | /* Now that we've done zero padding, add an exponent if needed. */\r | |
1166 | if (use_exp) {\r | |
1167 | *p++ = float_strings[OFS_E][0];\r | |
1168 | exp_len = sprintf(p, "%+.02d", exp);\r | |
1169 | p += exp_len;\r | |
1170 | }\r | |
1171 | exit:\r | |
1172 | if (buf) {\r | |
1173 | *p = '\0';\r | |
1174 | /* It's too late if this fails, as we've already stepped on\r | |
1175 | memory that isn't ours. But it's an okay debugging test. */\r | |
1176 | assert(p-buf < bufsize);\r | |
1177 | }\r | |
1178 | if (digits)\r | |
1179 | _Py_dg_freedtoa(digits);\r | |
1180 | \r | |
1181 | return buf;\r | |
1182 | }\r | |
1183 | \r | |
1184 | \r | |
1185 | PyAPI_FUNC(char *) PyOS_double_to_string(double val,\r | |
1186 | char format_code,\r | |
1187 | int precision,\r | |
1188 | int flags,\r | |
1189 | int *type)\r | |
1190 | {\r | |
1191 | char **float_strings = lc_float_strings;\r | |
1192 | int mode;\r | |
1193 | \r | |
1194 | /* Validate format_code, and map upper and lower case. Compute the\r | |
1195 | mode and make any adjustments as needed. */\r | |
1196 | switch (format_code) {\r | |
1197 | /* exponent */\r | |
1198 | case 'E':\r | |
1199 | float_strings = uc_float_strings;\r | |
1200 | format_code = 'e';\r | |
1201 | /* Fall through. */\r | |
1202 | case 'e':\r | |
1203 | mode = 2;\r | |
1204 | precision++;\r | |
1205 | break;\r | |
1206 | \r | |
1207 | /* fixed */\r | |
1208 | case 'F':\r | |
1209 | float_strings = uc_float_strings;\r | |
1210 | format_code = 'f';\r | |
1211 | /* Fall through. */\r | |
1212 | case 'f':\r | |
1213 | mode = 3;\r | |
1214 | break;\r | |
1215 | \r | |
1216 | /* general */\r | |
1217 | case 'G':\r | |
1218 | float_strings = uc_float_strings;\r | |
1219 | format_code = 'g';\r | |
1220 | /* Fall through. */\r | |
1221 | case 'g':\r | |
1222 | mode = 2;\r | |
1223 | /* precision 0 makes no sense for 'g' format; interpret as 1 */\r | |
1224 | if (precision == 0)\r | |
1225 | precision = 1;\r | |
1226 | break;\r | |
1227 | \r | |
1228 | /* repr format */\r | |
1229 | case 'r':\r | |
1230 | mode = 0;\r | |
1231 | /* Supplied precision is unused, must be 0. */\r | |
1232 | if (precision != 0) {\r | |
1233 | PyErr_BadInternalCall();\r | |
1234 | return NULL;\r | |
1235 | }\r | |
1236 | break;\r | |
1237 | \r | |
1238 | default:\r | |
1239 | PyErr_BadInternalCall();\r | |
1240 | return NULL;\r | |
1241 | }\r | |
1242 | \r | |
1243 | return format_float_short(val, format_code, mode, precision,\r | |
1244 | flags & Py_DTSF_SIGN,\r | |
1245 | flags & Py_DTSF_ADD_DOT_0,\r | |
1246 | flags & Py_DTSF_ALT,\r | |
1247 | float_strings, type);\r | |
1248 | }\r | |
1249 | #endif /* ifdef PY_NO_SHORT_FLOAT_REPR */\r |