blob: 66242d80781d23859084ca1c46a6eeafab1ac222 [file] [log] [blame]
Martin v. Löwis737ea822004-06-08 18:52:54 +00001/* -*- Mode: C; c-file-style: "python" -*- */
2
3#include <Python.h>
4#include <locale.h>
5
Martin v. Löwis737ea822004-06-08 18:52:54 +00006/**
7 * PyOS_ascii_strtod:
8 * @nptr: the string to convert to a numeric value.
9 * @endptr: if non-%NULL, it returns the character after
10 * the last character used in the conversion.
11 *
12 * Converts a string to a #gdouble value.
13 * This function behaves like the standard strtod() function
14 * does in the C locale. It does this without actually
15 * changing the current locale, since that would not be
16 * thread-safe.
17 *
18 * This function is typically used when reading configuration
19 * files or other non-user input that should be locale independent.
20 * To handle input from the user you should normally use the
21 * locale-sensitive system strtod() function.
22 *
23 * If the correct value would cause overflow, plus or minus %HUGE_VAL
24 * is returned (according to the sign of the value), and %ERANGE is
25 * stored in %errno. If the correct value would cause underflow,
26 * zero is returned and %ERANGE is stored in %errno.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000027 * If memory allocation fails, %ENOMEM is stored in %errno.
Martin v. Löwis737ea822004-06-08 18:52:54 +000028 *
29 * This function resets %errno before calling strtod() so that
30 * you can reliably detect overflow and underflow.
31 *
32 * Return value: the #gdouble value.
33 **/
Eric Smith0923d1d2009-04-16 20:16:10 +000034
35#ifndef PY_NO_SHORT_FLOAT_REPR
36
37double
Mark Dickinson725bfd82009-05-03 20:33:40 +000038_PyOS_ascii_strtod(const char *nptr, char **endptr)
Eric Smith0923d1d2009-04-16 20:16:10 +000039{
40 double result;
41 _Py_SET_53BIT_PRECISION_HEADER;
42
43 assert(nptr != NULL);
44 /* Set errno to zero, so that we can distinguish zero results
45 and underflows */
46 errno = 0;
47
48 _Py_SET_53BIT_PRECISION_START;
49 result = _Py_dg_strtod(nptr, endptr);
50 _Py_SET_53BIT_PRECISION_END;
51
52 return result;
53
54}
55
56#else
57
58/*
59 Use system strtod; since strtod is locale aware, we may
60 have to first fix the decimal separator.
61
62 Note that unlike _Py_dg_strtod, the system strtod may not always give
63 correctly rounded results.
64*/
65
Martin v. Löwis737ea822004-06-08 18:52:54 +000066double
Mark Dickinson725bfd82009-05-03 20:33:40 +000067_PyOS_ascii_strtod(const char *nptr, char **endptr)
Martin v. Löwis737ea822004-06-08 18:52:54 +000068{
69 char *fail_pos;
Neal Norwitz0e7a0ed2005-12-18 05:37:36 +000070 double val = -1.0;
Martin v. Löwis737ea822004-06-08 18:52:54 +000071 struct lconv *locale_data;
72 const char *decimal_point;
Neal Norwitzd39d8612006-01-08 01:03:36 +000073 size_t decimal_point_len;
Martin v. Löwis737ea822004-06-08 18:52:54 +000074 const char *p, *decimal_point_pos;
75 const char *end = NULL; /* Silence gcc */
Christian Heimesfaf2f632008-01-06 16:59:19 +000076 const char *digits_pos = NULL;
77 int negate = 0;
Martin v. Löwis737ea822004-06-08 18:52:54 +000078
Martin v. Löwis737ea822004-06-08 18:52:54 +000079 assert(nptr != NULL);
80
81 fail_pos = NULL;
82
83 locale_data = localeconv();
84 decimal_point = locale_data->decimal_point;
85 decimal_point_len = strlen(decimal_point);
86
87 assert(decimal_point_len != 0);
88
89 decimal_point_pos = NULL;
Christian Heimesfaf2f632008-01-06 16:59:19 +000090
Mark Dickinson6d65df12009-04-26 15:30:47 +000091 /* Set errno to zero, so that we can distinguish zero results
92 and underflows */
93 errno = 0;
94
Mark Dickinson725bfd82009-05-03 20:33:40 +000095 /* We process the optional sign manually, then pass the remainder to
96 the system strtod. This ensures that the result of an underflow
97 has the correct sign. (bug #1725) */
Christian Heimesfaf2f632008-01-06 16:59:19 +000098 p = nptr;
Christian Heimesfaf2f632008-01-06 16:59:19 +000099 /* Process leading sign, if present */
100 if (*p == '-') {
101 negate = 1;
102 p++;
Mark Dickinson6d65df12009-04-26 15:30:47 +0000103 }
104 else if (*p == '+') {
Christian Heimesfaf2f632008-01-06 16:59:19 +0000105 p++;
106 }
107
Mark Dickinson6d65df12009-04-26 15:30:47 +0000108 /* Parse infinities and nans */
109 if (*p == 'i' || *p == 'I') {
110 if (PyOS_strnicmp(p, "inf", 3) == 0) {
111 val = Py_HUGE_VAL;
112 if (PyOS_strnicmp(p+3, "inity", 5) == 0)
113 fail_pos = (char *)p+8;
114 else
115 fail_pos = (char *)p+3;
116 goto got_val;
117 }
118 else
119 goto invalid_string;
Christian Heimesfaf2f632008-01-06 16:59:19 +0000120 }
Mark Dickinson6d65df12009-04-26 15:30:47 +0000121#ifdef Py_NAN
122 if (*p == 'n' || *p == 'N') {
123 if (PyOS_strnicmp(p, "nan", 3) == 0) {
124 val = Py_NAN;
125 fail_pos = (char *)p+3;
126 goto got_val;
127 }
128 else
129 goto invalid_string;
130 }
131#endif
Christian Heimesfaf2f632008-01-06 16:59:19 +0000132
Mark Dickinson6d65df12009-04-26 15:30:47 +0000133 /* Some platform strtods accept hex floats; Python shouldn't (at the
134 moment), so we check explicitly for strings starting with '0x'. */
135 if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X'))
136 goto invalid_string;
137
138 /* Check that what's left begins with a digit or decimal point */
Eric Smith6dc46f52009-04-27 20:39:49 +0000139 if (!Py_ISDIGIT(*p) && *p != '.')
Mark Dickinson6d65df12009-04-26 15:30:47 +0000140 goto invalid_string;
141
142 digits_pos = p;
143 if (decimal_point[0] != '.' ||
Martin v. Löwis737ea822004-06-08 18:52:54 +0000144 decimal_point[1] != 0)
145 {
Mark Dickinson6d65df12009-04-26 15:30:47 +0000146 /* Look for a '.' in the input; if present, it'll need to be
147 swapped for the current locale's decimal point before we
148 call strtod. On the other hand, if we find the current
149 locale's decimal point then the input is invalid. */
Eric Smith6dc46f52009-04-27 20:39:49 +0000150 while (Py_ISDIGIT(*p))
Neal Norwitze7214a12005-12-18 05:03:17 +0000151 p++;
152
153 if (*p == '.')
Martin v. Löwis737ea822004-06-08 18:52:54 +0000154 {
Neal Norwitze7214a12005-12-18 05:03:17 +0000155 decimal_point_pos = p++;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000156
Mark Dickinson6d65df12009-04-26 15:30:47 +0000157 /* locate end of number */
Eric Smith6dc46f52009-04-27 20:39:49 +0000158 while (Py_ISDIGIT(*p))
Martin v. Löwis737ea822004-06-08 18:52:54 +0000159 p++;
160
Neal Norwitze7214a12005-12-18 05:03:17 +0000161 if (*p == 'e' || *p == 'E')
162 p++;
163 if (*p == '+' || *p == '-')
164 p++;
Eric Smith6dc46f52009-04-27 20:39:49 +0000165 while (Py_ISDIGIT(*p))
Neal Norwitze7214a12005-12-18 05:03:17 +0000166 p++;
167 end = p;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000168 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000169 else if (strncmp(p, decimal_point, decimal_point_len) == 0)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000170 /* Python bug #1417699 */
Mark Dickinson6d65df12009-04-26 15:30:47 +0000171 goto invalid_string;
Christian Heimesb186d002008-03-18 15:15:01 +0000172 /* For the other cases, we need not convert the decimal
173 point */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000174 }
175
Mark Dickinson6d65df12009-04-26 15:30:47 +0000176 if (decimal_point_pos) {
Martin v. Löwis737ea822004-06-08 18:52:54 +0000177 char *copy, *c;
Mark Dickinson6d65df12009-04-26 15:30:47 +0000178 /* Create a copy of the input, with the '.' converted to the
179 locale-specific decimal point */
Christian Heimesfaf2f632008-01-06 16:59:19 +0000180 copy = (char *)PyMem_MALLOC(end - digits_pos +
181 1 + decimal_point_len);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000182 if (copy == NULL) {
Mark Dickinson725bfd82009-05-03 20:33:40 +0000183 *endptr = (char *)nptr;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000184 errno = ENOMEM;
185 return val;
186 }
Martin v. Löwis737ea822004-06-08 18:52:54 +0000187
188 c = copy;
Christian Heimesfaf2f632008-01-06 16:59:19 +0000189 memcpy(c, digits_pos, decimal_point_pos - digits_pos);
190 c += decimal_point_pos - digits_pos;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000191 memcpy(c, decimal_point, decimal_point_len);
192 c += decimal_point_len;
Christian Heimesb186d002008-03-18 15:15:01 +0000193 memcpy(c, decimal_point_pos + 1,
194 end - (decimal_point_pos + 1));
Martin v. Löwis737ea822004-06-08 18:52:54 +0000195 c += end - (decimal_point_pos + 1);
196 *c = 0;
197
198 val = strtod(copy, &fail_pos);
199
200 if (fail_pos)
201 {
202 if (fail_pos > decimal_point_pos)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000203 fail_pos = (char *)digits_pos +
204 (fail_pos - copy) -
205 (decimal_point_len - 1);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000206 else
Christian Heimesfaf2f632008-01-06 16:59:19 +0000207 fail_pos = (char *)digits_pos +
208 (fail_pos - copy);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000209 }
210
Thomas Wouters477c8d52006-05-27 19:21:47 +0000211 PyMem_FREE(copy);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000212
213 }
Neal Norwitze7214a12005-12-18 05:03:17 +0000214 else {
Christian Heimesfaf2f632008-01-06 16:59:19 +0000215 val = strtod(digits_pos, &fail_pos);
Neal Norwitze7214a12005-12-18 05:03:17 +0000216 }
Martin v. Löwis737ea822004-06-08 18:52:54 +0000217
Christian Heimesfaf2f632008-01-06 16:59:19 +0000218 if (fail_pos == digits_pos)
Mark Dickinson6d65df12009-04-26 15:30:47 +0000219 goto invalid_string;
Christian Heimesfaf2f632008-01-06 16:59:19 +0000220
Mark Dickinson6d65df12009-04-26 15:30:47 +0000221 got_val:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000222 if (negate && fail_pos != nptr)
223 val = -val;
Mark Dickinson725bfd82009-05-03 20:33:40 +0000224 *endptr = fail_pos;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000225
226 return val;
Mark Dickinson6d65df12009-04-26 15:30:47 +0000227
228 invalid_string:
Mark Dickinson725bfd82009-05-03 20:33:40 +0000229 *endptr = (char*)nptr;
Mark Dickinson6d65df12009-04-26 15:30:47 +0000230 errno = EINVAL;
231 return -1.0;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000232}
233
Eric Smith0923d1d2009-04-16 20:16:10 +0000234#endif
235
Mark Dickinson725bfd82009-05-03 20:33:40 +0000236/* PyOS_ascii_strtod is DEPRECATED in Python 3.1 */
237
238double
239PyOS_ascii_strtod(const char *nptr, char **endptr)
240{
241 char *fail_pos;
242 const char *p;
243 double x;
244
245 if (PyErr_WarnEx(PyExc_DeprecationWarning,
246 "PyOS_ascii_strtod and PyOS_ascii_atof are "
247 "deprecated. Use PyOS_string_to_double "
248 "instead.", 1) < 0)
249 return -1.0;
250
251 /* _PyOS_ascii_strtod already does everything that we want,
252 except that it doesn't parse leading whitespace */
253 p = nptr;
254 while (Py_ISSPACE(*p))
255 p++;
256 x = _PyOS_ascii_strtod(p, &fail_pos);
257 if (fail_pos == p)
258 fail_pos = (char *)nptr;
259 if (endptr)
260 *endptr = (char *)fail_pos;
261 return x;
262}
263
264/* PyOS_ascii_strtod is DEPRECATED in Python 3.1 */
265
Eric Smith0923d1d2009-04-16 20:16:10 +0000266double
267PyOS_ascii_atof(const char *nptr)
268{
269 return PyOS_ascii_strtod(nptr, NULL);
270}
271
Mark Dickinson725bfd82009-05-03 20:33:40 +0000272/* PyOS_string_to_double is the recommended replacement for the deprecated
273 PyOS_ascii_strtod and PyOS_ascii_atof functions. It converts a
274 null-terminated byte string s (interpreted as a string of ASCII characters)
275 to a float. The string should not have leading or trailing whitespace (in
276 contrast, PyOS_ascii_strtod allows leading whitespace but not trailing
277 whitespace). The conversion is independent of the current locale.
278
279 If endptr is NULL, try to convert the whole string. Raise ValueError and
280 return -1.0 if the string is not a valid representation of a floating-point
281 number.
282
283 If endptr is non-NULL, try to convert as much of the string as possible.
284 If no initial segment of the string is the valid representation of a
285 floating-point number then *endptr is set to point to the beginning of the
286 string, -1.0 is returned and again ValueError is raised.
287
288 On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine),
289 if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python
290 exception is raised. Otherwise, overflow_exception should point to a
291 a Python exception, this exception will be raised, -1.0 will be returned,
292 and *endptr will point just past the end of the converted value.
293
294 If any other failure occurs (for example lack of memory), -1.0 is returned
295 and the appropriate Python exception will have been set.
296*/
297
298double
299PyOS_string_to_double(const char *s,
300 char **endptr,
301 PyObject *overflow_exception)
302{
303 double x, result=-1.0;
304 char *fail_pos;
305
306 errno = 0;
307 PyFPE_START_PROTECT("PyOS_string_to_double", return -1.0)
308 x = _PyOS_ascii_strtod(s, &fail_pos);
309 PyFPE_END_PROTECT(x)
310
311 if (errno == ENOMEM) {
312 PyErr_NoMemory();
313 fail_pos = (char *)s;
314 }
315 else if (!endptr && (fail_pos == s || *fail_pos != '\0'))
316 PyErr_Format(PyExc_ValueError,
317 "could not convert string to float: "
318 "%.200s", s);
319 else if (fail_pos == s)
320 PyErr_Format(PyExc_ValueError,
321 "could not convert string to float: "
322 "%.200s", s);
323 else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception)
324 PyErr_Format(overflow_exception,
325 "value too large to convert to float: "
326 "%.200s", s);
327 else
328 result = x;
329
330 if (endptr != NULL)
331 *endptr = fail_pos;
332 return result;
333}
Eric Smith0923d1d2009-04-16 20:16:10 +0000334
Eric Smithb2c7af82008-04-30 02:12:09 +0000335/* Given a string that may have a decimal point in the current
336 locale, change it back to a dot. Since the string cannot get
337 longer, no need for a maximum buffer size parameter. */
338Py_LOCAL_INLINE(void)
339change_decimal_from_locale_to_dot(char* buffer)
340{
341 struct lconv *locale_data = localeconv();
342 const char *decimal_point = locale_data->decimal_point;
343
344 if (decimal_point[0] != '.' || decimal_point[1] != 0) {
345 size_t decimal_point_len = strlen(decimal_point);
346
347 if (*buffer == '+' || *buffer == '-')
348 buffer++;
Eric Smith6dc46f52009-04-27 20:39:49 +0000349 while (Py_ISDIGIT(*buffer))
Eric Smithb2c7af82008-04-30 02:12:09 +0000350 buffer++;
351 if (strncmp(buffer, decimal_point, decimal_point_len) == 0) {
352 *buffer = '.';
353 buffer++;
354 if (decimal_point_len > 1) {
355 /* buffer needs to get smaller */
356 size_t rest_len = strlen(buffer +
357 (decimal_point_len - 1));
358 memmove(buffer,
359 buffer + (decimal_point_len - 1),
360 rest_len);
361 buffer[rest_len] = 0;
362 }
363 }
364 }
365}
366
Martin v. Löwis737ea822004-06-08 18:52:54 +0000367
Christian Heimesc3f30c42008-02-22 16:37:40 +0000368/* From the C99 standard, section 7.19.6:
369The exponent always contains at least two digits, and only as many more digits
370as necessary to represent the exponent.
371*/
372#define MIN_EXPONENT_DIGITS 2
373
Eric Smithb2c7af82008-04-30 02:12:09 +0000374/* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS
375 in length. */
376Py_LOCAL_INLINE(void)
Mark Dickinsonce95e562009-04-26 20:02:24 +0000377ensure_minimum_exponent_length(char* buffer, size_t buf_size)
Eric Smithb2c7af82008-04-30 02:12:09 +0000378{
379 char *p = strpbrk(buffer, "eE");
380 if (p && (*(p + 1) == '-' || *(p + 1) == '+')) {
381 char *start = p + 2;
382 int exponent_digit_cnt = 0;
383 int leading_zero_cnt = 0;
384 int in_leading_zeros = 1;
385 int significant_digit_cnt;
386
387 /* Skip over the exponent and the sign. */
388 p += 2;
389
390 /* Find the end of the exponent, keeping track of leading
391 zeros. */
Eric Smith6dc46f52009-04-27 20:39:49 +0000392 while (*p && Py_ISDIGIT(*p)) {
Eric Smithb2c7af82008-04-30 02:12:09 +0000393 if (in_leading_zeros && *p == '0')
394 ++leading_zero_cnt;
395 if (*p != '0')
396 in_leading_zeros = 0;
397 ++p;
398 ++exponent_digit_cnt;
399 }
400
401 significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt;
402 if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) {
403 /* If there are 2 exactly digits, we're done,
404 regardless of what they contain */
405 }
406 else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) {
407 int extra_zeros_cnt;
408
409 /* There are more than 2 digits in the exponent. See
410 if we can delete some of the leading zeros */
411 if (significant_digit_cnt < MIN_EXPONENT_DIGITS)
412 significant_digit_cnt = MIN_EXPONENT_DIGITS;
413 extra_zeros_cnt = exponent_digit_cnt -
414 significant_digit_cnt;
415
416 /* Delete extra_zeros_cnt worth of characters from the
417 front of the exponent */
418 assert(extra_zeros_cnt >= 0);
419
420 /* Add one to significant_digit_cnt to copy the
421 trailing 0 byte, thus setting the length */
422 memmove(start,
423 start + extra_zeros_cnt,
424 significant_digit_cnt + 1);
425 }
426 else {
427 /* If there are fewer than 2 digits, add zeros
428 until there are 2, if there's enough room */
429 int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt;
430 if (start + zeros + exponent_digit_cnt + 1
431 < buffer + buf_size) {
432 memmove(start + zeros, start,
433 exponent_digit_cnt + 1);
434 memset(start, '0', zeros);
435 }
436 }
437 }
438}
439
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000440/* Remove trailing zeros after the decimal point from a numeric string; also
441 remove the decimal point if all digits following it are zero. The numeric
442 string must end in '\0', and should not have any leading or trailing
443 whitespace. Assumes that the decimal point is '.'. */
Eric Smithb2c7af82008-04-30 02:12:09 +0000444Py_LOCAL_INLINE(void)
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000445remove_trailing_zeros(char *buffer)
Eric Smithb2c7af82008-04-30 02:12:09 +0000446{
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000447 char *old_fraction_end, *new_fraction_end, *end, *p;
448
449 p = buffer;
450 if (*p == '-' || *p == '+')
451 /* Skip leading sign, if present */
452 ++p;
453 while (Py_ISDIGIT(*p))
454 ++p;
455
456 /* if there's no decimal point there's nothing to do */
457 if (*p++ != '.')
458 return;
459
460 /* scan any digits after the point */
461 while (Py_ISDIGIT(*p))
462 ++p;
463 old_fraction_end = p;
464
465 /* scan up to ending '\0' */
466 while (*p != '\0')
467 p++;
468 /* +1 to make sure that we move the null byte as well */
469 end = p+1;
470
471 /* scan back from fraction_end, looking for removable zeros */
472 p = old_fraction_end;
473 while (*(p-1) == '0')
474 --p;
475 /* and remove point if we've got that far */
476 if (*(p-1) == '.')
477 --p;
478 new_fraction_end = p;
479
480 memmove(new_fraction_end, old_fraction_end, end-old_fraction_end);
481}
482
483/* Ensure that buffer has a decimal point in it. The decimal point will not
484 be in the current locale, it will always be '.'. Don't add a decimal point
485 if an exponent is present. Also, convert to exponential notation where
486 adding a '.0' would produce too many significant digits (see issue 5864).
487
488 Returns a pointer to the fixed buffer, or NULL on failure.
489*/
490Py_LOCAL_INLINE(char *)
491ensure_decimal_point(char* buffer, size_t buf_size, int precision)
492{
493 int digit_count, insert_count = 0, convert_to_exp = 0;
494 char *chars_to_insert, *digits_start;
Eric Smithb2c7af82008-04-30 02:12:09 +0000495
496 /* search for the first non-digit character */
497 char *p = buffer;
Eric Smith2ad79e82008-07-19 00:33:23 +0000498 if (*p == '-' || *p == '+')
499 /* Skip leading sign, if present. I think this could only
500 ever be '-', but it can't hurt to check for both. */
501 ++p;
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000502 digits_start = p;
Eric Smith6dc46f52009-04-27 20:39:49 +0000503 while (*p && Py_ISDIGIT(*p))
Eric Smithb2c7af82008-04-30 02:12:09 +0000504 ++p;
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000505 digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int);
Eric Smithb2c7af82008-04-30 02:12:09 +0000506
507 if (*p == '.') {
Eric Smith6dc46f52009-04-27 20:39:49 +0000508 if (Py_ISDIGIT(*(p+1))) {
Eric Smithb2c7af82008-04-30 02:12:09 +0000509 /* Nothing to do, we already have a decimal
510 point and a digit after it */
511 }
512 else {
513 /* We have a decimal point, but no following
514 digit. Insert a zero after the decimal. */
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000515 /* can't ever get here via PyOS_double_to_string */
516 assert(precision == -1);
Eric Smithb2c7af82008-04-30 02:12:09 +0000517 ++p;
518 chars_to_insert = "0";
519 insert_count = 1;
520 }
521 }
Eric Smith0923d1d2009-04-16 20:16:10 +0000522 else if (!(*p == 'e' || *p == 'E')) {
523 /* Don't add ".0" if we have an exponent. */
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000524 if (digit_count == precision) {
525 /* issue 5864: don't add a trailing .0 in the case
526 where the '%g'-formatted result already has as many
527 significant digits as were requested. Switch to
528 exponential notation instead. */
529 convert_to_exp = 1;
530 /* no exponent, no point, and we shouldn't land here
531 for infs and nans, so we must be at the end of the
532 string. */
533 assert(*p == '\0');
534 }
535 else {
536 assert(precision == -1 || digit_count < precision);
537 chars_to_insert = ".0";
538 insert_count = 2;
539 }
Eric Smithb2c7af82008-04-30 02:12:09 +0000540 }
541 if (insert_count) {
542 size_t buf_len = strlen(buffer);
543 if (buf_len + insert_count + 1 >= buf_size) {
544 /* If there is not enough room in the buffer
545 for the additional text, just skip it. It's
546 not worth generating an error over. */
547 }
548 else {
549 memmove(p + insert_count, p,
550 buffer + strlen(buffer) - p + 1);
551 memcpy(p, chars_to_insert, insert_count);
552 }
553 }
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000554 if (convert_to_exp) {
555 int written;
556 size_t buf_avail;
557 p = digits_start;
558 /* insert decimal point */
559 assert(digit_count >= 1);
560 memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */
561 p[1] = '.';
562 p += digit_count+1;
563 assert(p <= buf_size+buffer);
564 buf_avail = buf_size+buffer-p;
565 if (buf_avail == 0)
566 return NULL;
567 /* Add exponent. It's okay to use lower case 'e': we only
568 arrive here as a result of using the empty format code or
569 repr/str builtins and those never want an upper case 'E' */
570 written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1);
571 if (!(0 <= written &&
572 written < Py_SAFE_DOWNCAST(buf_avail, size_t, int)))
573 /* output truncated, or something else bad happened */
574 return NULL;
575 remove_trailing_zeros(buffer);
576 }
577 return buffer;
Eric Smithb2c7af82008-04-30 02:12:09 +0000578}
579
Christian Heimesc3f30c42008-02-22 16:37:40 +0000580/* see FORMATBUFLEN in unicodeobject.c */
581#define FLOAT_FORMATBUFLEN 120
582
Martin v. Löwis737ea822004-06-08 18:52:54 +0000583/**
584 * PyOS_ascii_formatd:
585 * @buffer: A buffer to place the resulting string in
Christian Heimesb186d002008-03-18 15:15:01 +0000586 * @buf_size: The length of the buffer.
Martin v. Löwis737ea822004-06-08 18:52:54 +0000587 * @format: The printf()-style format to use for the
588 * code to use for converting.
589 * @d: The #gdouble to convert
590 *
591 * Converts a #gdouble to a string, using the '.' as
592 * decimal point. To format the number you pass in
593 * a printf()-style format string. Allowed conversion
Eric Smith0923d1d2009-04-16 20:16:10 +0000594 * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'.
Martin v. Löwis737ea822004-06-08 18:52:54 +0000595 *
Christian Heimesb186d002008-03-18 15:15:01 +0000596 * 'Z' is the same as 'g', except it always has a decimal and
597 * at least one digit after the decimal.
Christian Heimesc3f30c42008-02-22 16:37:40 +0000598 *
Martin v. Löwis737ea822004-06-08 18:52:54 +0000599 * Return value: The pointer to the buffer with the converted string.
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000600 * On failure returns NULL but does not set any Python exception.
Martin v. Löwis737ea822004-06-08 18:52:54 +0000601 **/
602char *
Eric Smithcc32a112009-04-26 21:35:14 +0000603_PyOS_ascii_formatd(char *buffer,
Christian Heimesb186d002008-03-18 15:15:01 +0000604 size_t buf_size,
Martin v. Löwis737ea822004-06-08 18:52:54 +0000605 const char *format,
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000606 double d,
607 int precision)
Martin v. Löwis737ea822004-06-08 18:52:54 +0000608{
Martin v. Löwis737ea822004-06-08 18:52:54 +0000609 char format_char;
Christian Heimesc3f30c42008-02-22 16:37:40 +0000610 size_t format_len = strlen(format);
611
Christian Heimesb186d002008-03-18 15:15:01 +0000612 /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but
613 also with at least one character past the decimal. */
Christian Heimesc3f30c42008-02-22 16:37:40 +0000614 char tmp_format[FLOAT_FORMATBUFLEN];
Martin v. Löwis737ea822004-06-08 18:52:54 +0000615
Christian Heimesc3f30c42008-02-22 16:37:40 +0000616 /* The last character in the format string must be the format char */
617 format_char = format[format_len - 1];
Martin v. Löwis737ea822004-06-08 18:52:54 +0000618
Martin v. Löwis737ea822004-06-08 18:52:54 +0000619 if (format[0] != '%')
620 return NULL;
621
Christian Heimesc3f30c42008-02-22 16:37:40 +0000622 /* I'm not sure why this test is here. It's ensuring that the format
623 string after the first character doesn't have a single quote, a
624 lowercase l, or a percent. This is the reverse of the commented-out
625 test about 10 lines ago. */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000626 if (strpbrk(format + 1, "'l%"))
627 return NULL;
628
Christian Heimesb186d002008-03-18 15:15:01 +0000629 /* Also curious about this function is that it accepts format strings
630 like "%xg", which are invalid for floats. In general, the
631 interface to this function is not very good, but changing it is
632 difficult because it's a public API. */
633
Martin v. Löwis737ea822004-06-08 18:52:54 +0000634 if (!(format_char == 'e' || format_char == 'E' ||
635 format_char == 'f' || format_char == 'F' ||
Christian Heimesc3f30c42008-02-22 16:37:40 +0000636 format_char == 'g' || format_char == 'G' ||
Eric Smith0923d1d2009-04-16 20:16:10 +0000637 format_char == 'Z'))
Martin v. Löwis737ea822004-06-08 18:52:54 +0000638 return NULL;
639
Eric Smith0923d1d2009-04-16 20:16:10 +0000640 /* Map 'Z' format_char to 'g', by copying the format string and
Christian Heimesb186d002008-03-18 15:15:01 +0000641 replacing the final char with a 'g' */
Eric Smith0923d1d2009-04-16 20:16:10 +0000642 if (format_char == 'Z') {
Christian Heimesc3f30c42008-02-22 16:37:40 +0000643 if (format_len + 1 >= sizeof(tmp_format)) {
644 /* The format won't fit in our copy. Error out. In
Christian Heimesb186d002008-03-18 15:15:01 +0000645 practice, this will never happen and will be
646 detected by returning NULL */
Christian Heimesc3f30c42008-02-22 16:37:40 +0000647 return NULL;
648 }
649 strcpy(tmp_format, format);
650 tmp_format[format_len - 1] = 'g';
651 format = tmp_format;
652 }
Martin v. Löwis737ea822004-06-08 18:52:54 +0000653
Christian Heimesb186d002008-03-18 15:15:01 +0000654
Christian Heimesc3f30c42008-02-22 16:37:40 +0000655 /* Have PyOS_snprintf do the hard work */
Christian Heimesb186d002008-03-18 15:15:01 +0000656 PyOS_snprintf(buffer, buf_size, format, d);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000657
Eric Smithb2c7af82008-04-30 02:12:09 +0000658 /* Do various fixups on the return string */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000659
Eric Smithb2c7af82008-04-30 02:12:09 +0000660 /* Get the current locale, and find the decimal point string.
Eric Smith0923d1d2009-04-16 20:16:10 +0000661 Convert that string back to a dot. */
662 change_decimal_from_locale_to_dot(buffer);
Christian Heimesc3f30c42008-02-22 16:37:40 +0000663
664 /* If an exponent exists, ensure that the exponent is at least
665 MIN_EXPONENT_DIGITS digits, providing the buffer is large enough
666 for the extra zeros. Also, if there are more than
667 MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get
668 back to MIN_EXPONENT_DIGITS */
Mark Dickinsonce95e562009-04-26 20:02:24 +0000669 ensure_minimum_exponent_length(buffer, buf_size);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000670
Christian Heimesb186d002008-03-18 15:15:01 +0000671 /* If format_char is 'Z', make sure we have at least one character
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000672 after the decimal point (and make sure we have a decimal point);
673 also switch to exponential notation in some edge cases where the
674 extra character would produce more significant digits that we
675 really want. */
Eric Smithb2c7af82008-04-30 02:12:09 +0000676 if (format_char == 'Z')
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000677 buffer = ensure_decimal_point(buffer, buf_size, precision);
Christian Heimesb186d002008-03-18 15:15:01 +0000678
Martin v. Löwis737ea822004-06-08 18:52:54 +0000679 return buffer;
680}
681
Eric Smithcc32a112009-04-26 21:35:14 +0000682char *
683PyOS_ascii_formatd(char *buffer,
684 size_t buf_size,
685 const char *format,
686 double d)
687{
688 if (PyErr_WarnEx(PyExc_DeprecationWarning,
689 "PyOS_ascii_formatd is deprecated, "
690 "use PyOS_double_to_string instead", 1) < 0)
691 return NULL;
692
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000693 return _PyOS_ascii_formatd(buffer, buf_size, format, d, -1);
Eric Smithcc32a112009-04-26 21:35:14 +0000694}
695
Eric Smith0923d1d2009-04-16 20:16:10 +0000696#ifdef PY_NO_SHORT_FLOAT_REPR
697
698/* The fallback code to use if _Py_dg_dtoa is not available. */
699
700PyAPI_FUNC(char *) PyOS_double_to_string(double val,
701 char format_code,
702 int precision,
703 int flags,
704 int *type)
Martin v. Löwis737ea822004-06-08 18:52:54 +0000705{
Eric Smith0923d1d2009-04-16 20:16:10 +0000706 char format[32];
Mark Dickinsonf489caf2009-05-01 11:42:00 +0000707 Py_ssize_t bufsize;
708 char *buf;
709 int t, exp;
Eric Smith0923d1d2009-04-16 20:16:10 +0000710 int upper = 0;
711
712 /* Validate format_code, and map upper and lower case */
713 switch (format_code) {
714 case 'e': /* exponent */
715 case 'f': /* fixed */
716 case 'g': /* general */
717 break;
718 case 'E':
719 upper = 1;
720 format_code = 'e';
721 break;
722 case 'F':
723 upper = 1;
724 format_code = 'f';
725 break;
726 case 'G':
727 upper = 1;
728 format_code = 'g';
729 break;
730 case 'r': /* repr format */
731 /* Supplied precision is unused, must be 0. */
732 if (precision != 0) {
733 PyErr_BadInternalCall();
734 return NULL;
735 }
736 precision = 17;
737 format_code = 'g';
738 break;
739 case 's': /* str format */
740 /* Supplied precision is unused, must be 0. */
741 if (precision != 0) {
742 PyErr_BadInternalCall();
743 return NULL;
744 }
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000745 precision = 12;
746 format_code = 'g';
Eric Smith0923d1d2009-04-16 20:16:10 +0000747 break;
748 default:
749 PyErr_BadInternalCall();
750 return NULL;
751 }
752
Mark Dickinsonf489caf2009-05-01 11:42:00 +0000753 /* Here's a quick-and-dirty calculation to figure out how big a buffer
754 we need. In general, for a finite float we need:
755
756 1 byte for each digit of the decimal significand, and
757
758 1 for a possible sign
759 1 for a possible decimal point
760 2 for a possible [eE][+-]
761 1 for each digit of the exponent; if we allow 19 digits
762 total then we're safe up to exponents of 2**63.
763 1 for the trailing nul byte
764
765 This gives a total of 24 + the number of digits in the significand,
766 and the number of digits in the significand is:
767
768 for 'g' format: at most precision, except possibly
769 when precision == 0, when it's 1.
770 for 'e' format: precision+1
771 for 'f' format: precision digits after the point, at least 1
772 before. To figure out how many digits appear before the point
773 we have to examine the size of the number. If fabs(val) < 1.0
774 then there will be only one digit before the point. If
775 fabs(val) >= 1.0, then there are at most
776
777 1+floor(log10(ceiling(fabs(val))))
778
779 digits before the point (where the 'ceiling' allows for the
780 possibility that the rounding rounds the integer part of val
781 up). A safe upper bound for the above quantity is
782 1+floor(exp/3), where exp is the unique integer such that 0.5
783 <= fabs(val)/2**exp < 1.0. This exp can be obtained from
784 frexp.
785
786 So we allow room for precision+1 digits for all formats, plus an
787 extra floor(exp/3) digits for 'f' format.
788
789 */
790
791 if (Py_IS_NAN(val) || Py_IS_INFINITY(val))
792 /* 3 for 'inf'/'nan', 1 for sign, 1 for '\0' */
793 bufsize = 5;
794 else {
795 bufsize = 25 + precision;
796 if (format_code == 'f' && fabs(val) >= 1.0) {
797 frexp(val, &exp);
798 bufsize += exp/3;
799 }
800 }
801
802 buf = PyMem_Malloc(bufsize);
803 if (buf == NULL) {
804 PyErr_NoMemory();
805 return NULL;
806 }
807
Eric Smith0923d1d2009-04-16 20:16:10 +0000808 /* Handle nan and inf. */
809 if (Py_IS_NAN(val)) {
810 strcpy(buf, "nan");
811 t = Py_DTST_NAN;
812 } else if (Py_IS_INFINITY(val)) {
813 if (copysign(1., val) == 1.)
814 strcpy(buf, "inf");
815 else
816 strcpy(buf, "-inf");
817 t = Py_DTST_INFINITE;
818 } else {
819 t = Py_DTST_FINITE;
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000820 if (flags & Py_DTSF_ADD_DOT_0)
Eric Smith0923d1d2009-04-16 20:16:10 +0000821 format_code = 'Z';
822
Eric Smithcc32a112009-04-26 21:35:14 +0000823 PyOS_snprintf(format, sizeof(format), "%%%s.%i%c",
824 (flags & Py_DTSF_ALT ? "#" : ""), precision,
825 format_code);
Mark Dickinsonf489caf2009-05-01 11:42:00 +0000826 _PyOS_ascii_formatd(buf, bufsize, format, val, precision);
Eric Smith0923d1d2009-04-16 20:16:10 +0000827 }
828
Mark Dickinsonad476da2009-04-23 19:14:16 +0000829 /* Add sign when requested. It's convenient (esp. when formatting
830 complex numbers) to include a sign even for inf and nan. */
Mark Dickinsonf489caf2009-05-01 11:42:00 +0000831 if (flags & Py_DTSF_SIGN && buf[0] != '-') {
832 size_t len = strlen(buf);
833 /* the bufsize calculations above should ensure that we've got
834 space to add a sign */
835 assert((size_t)bufsize >= len+2);
836 memmove(buf+1, buf, len+1);
837 buf[0] = '+';
838 }
Eric Smith0923d1d2009-04-16 20:16:10 +0000839 if (upper) {
840 /* Convert to upper case. */
841 char *p1;
Mark Dickinsonf489caf2009-05-01 11:42:00 +0000842 for (p1 = buf; *p1; p1++)
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000843 *p1 = Py_TOUPPER(*p1);
Eric Smith0923d1d2009-04-16 20:16:10 +0000844 }
845
846 if (type)
847 *type = t;
Mark Dickinsonf489caf2009-05-01 11:42:00 +0000848 return buf;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000849}
Eric Smith0923d1d2009-04-16 20:16:10 +0000850
851#else
852
853/* _Py_dg_dtoa is available. */
854
855/* I'm using a lookup table here so that I don't have to invent a non-locale
856 specific way to convert to uppercase */
857#define OFS_INF 0
858#define OFS_NAN 1
859#define OFS_E 2
860
861/* The lengths of these are known to the code below, so don't change them */
862static char *lc_float_strings[] = {
863 "inf",
864 "nan",
865 "e",
866};
867static char *uc_float_strings[] = {
868 "INF",
869 "NAN",
870 "E",
871};
872
873
874/* Convert a double d to a string, and return a PyMem_Malloc'd block of
875 memory contain the resulting string.
876
877 Arguments:
878 d is the double to be converted
879 format_code is one of 'e', 'f', 'g', 'r' or 's'. 'e', 'f' and 'g'
880 correspond to '%e', '%f' and '%g'; 'r' and 's' correspond
881 to repr and str.
882 mode is one of '0', '2' or '3', and is completely determined by
883 format_code: 'e', 'g' and 's' use mode 2; 'f' mode 3, 'r' mode 0.
884 precision is the desired precision
885 always_add_sign is nonzero if a '+' sign should be included for positive
886 numbers
887 add_dot_0_if_integer is nonzero if integers in non-exponential form
888 should have ".0" added. Only applies to format codes 'r', 's', and 'g'.
889 use_alt_formatting is nonzero if alternative formatting should be
890 used. Only applies to format codes 'e', 'f' and 'g'.
891 type, if non-NULL, will be set to one of these constants to identify
892 the type of the 'd' argument:
893 Py_DTST_FINITE
894 Py_DTST_INFINITE
895 Py_DTST_NAN
896
897 Returns a PyMem_Malloc'd block of memory containing the resulting string,
898 or NULL on error. If NULL is returned, the Python error has been set.
899 */
900
901static char *
902format_float_short(double d, char format_code,
903 int mode, Py_ssize_t precision,
904 int always_add_sign, int add_dot_0_if_integer,
905 int use_alt_formatting, char **float_strings, int *type)
906{
907 char *buf = NULL;
908 char *p = NULL;
909 Py_ssize_t bufsize = 0;
910 char *digits, *digits_end;
911 int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0;
912 Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end;
913 _Py_SET_53BIT_PRECISION_HEADER;
914
915 /* _Py_dg_dtoa returns a digit string (no decimal point or exponent).
916 Must be matched by a call to _Py_dg_freedtoa. */
917 _Py_SET_53BIT_PRECISION_START;
918 digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign,
919 &digits_end);
920 _Py_SET_53BIT_PRECISION_END;
921
922 decpt = (Py_ssize_t)decpt_as_int;
923 if (digits == NULL) {
924 /* The only failure mode is no memory. */
925 PyErr_NoMemory();
926 goto exit;
927 }
928 assert(digits_end != NULL && digits_end >= digits);
929 digits_len = digits_end - digits;
930
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000931 if (digits_len && !Py_ISDIGIT(digits[0])) {
Eric Smith0923d1d2009-04-16 20:16:10 +0000932 /* Infinities and nans here; adapt Gay's output,
933 so convert Infinity to inf and NaN to nan, and
934 ignore sign of nan. Then return. */
935
Mark Dickinsonad476da2009-04-23 19:14:16 +0000936 /* ignore the actual sign of a nan */
937 if (digits[0] == 'n' || digits[0] == 'N')
938 sign = 0;
939
Eric Smith0923d1d2009-04-16 20:16:10 +0000940 /* We only need 5 bytes to hold the result "+inf\0" . */
941 bufsize = 5; /* Used later in an assert. */
942 buf = (char *)PyMem_Malloc(bufsize);
943 if (buf == NULL) {
944 PyErr_NoMemory();
945 goto exit;
946 }
947 p = buf;
948
Mark Dickinsonad476da2009-04-23 19:14:16 +0000949 if (sign == 1) {
950 *p++ = '-';
951 }
952 else if (always_add_sign) {
953 *p++ = '+';
954 }
Eric Smith0923d1d2009-04-16 20:16:10 +0000955 if (digits[0] == 'i' || digits[0] == 'I') {
Eric Smith0923d1d2009-04-16 20:16:10 +0000956 strncpy(p, float_strings[OFS_INF], 3);
957 p += 3;
958
959 if (type)
960 *type = Py_DTST_INFINITE;
961 }
962 else if (digits[0] == 'n' || digits[0] == 'N') {
Eric Smith0923d1d2009-04-16 20:16:10 +0000963 strncpy(p, float_strings[OFS_NAN], 3);
964 p += 3;
965
966 if (type)
967 *type = Py_DTST_NAN;
968 }
969 else {
970 /* shouldn't get here: Gay's code should always return
971 something starting with a digit, an 'I', or 'N' */
972 strncpy(p, "ERR", 3);
973 p += 3;
974 assert(0);
975 }
976 goto exit;
977 }
978
979 /* The result must be finite (not inf or nan). */
980 if (type)
981 *type = Py_DTST_FINITE;
982
983
984 /* We got digits back, format them. We may need to pad 'digits'
985 either on the left or right (or both) with extra zeros, so in
986 general the resulting string has the form
987
988 [<sign>]<zeros><digits><zeros>[<exponent>]
989
990 where either of the <zeros> pieces could be empty, and there's a
991 decimal point that could appear either in <digits> or in the
992 leading or trailing <zeros>.
993
994 Imagine an infinite 'virtual' string vdigits, consisting of the
995 string 'digits' (starting at index 0) padded on both the left and
996 right with infinite strings of zeros. We want to output a slice
997
998 vdigits[vdigits_start : vdigits_end]
999
1000 of this virtual string. Thus if vdigits_start < 0 then we'll end
1001 up producing some leading zeros; if vdigits_end > digits_len there
1002 will be trailing zeros in the output. The next section of code
1003 determines whether to use an exponent or not, figures out the
1004 position 'decpt' of the decimal point, and computes 'vdigits_start'
1005 and 'vdigits_end'. */
1006 vdigits_end = digits_len;
1007 switch (format_code) {
1008 case 'e':
1009 use_exp = 1;
1010 vdigits_end = precision;
1011 break;
1012 case 'f':
1013 vdigits_end = decpt + precision;
1014 break;
1015 case 'g':
Mark Dickinsond3ca5572009-04-29 18:47:07 +00001016 if (decpt <= -4 || decpt >
1017 (add_dot_0_if_integer ? precision-1 : precision))
Eric Smith0923d1d2009-04-16 20:16:10 +00001018 use_exp = 1;
1019 if (use_alt_formatting)
1020 vdigits_end = precision;
1021 break;
1022 case 'r':
1023 /* convert to exponential format at 1e16. We used to convert
1024 at 1e17, but that gives odd-looking results for some values
1025 when a 16-digit 'shortest' repr is padded with bogus zeros.
1026 For example, repr(2e16+8) would give 20000000000000010.0;
1027 the true value is 20000000000000008.0. */
1028 if (decpt <= -4 || decpt > 16)
1029 use_exp = 1;
1030 break;
1031 case 's':
1032 /* if we're forcing a digit after the point, convert to
1033 exponential format at 1e11. If not, convert at 1e12. */
1034 if (decpt <= -4 || decpt >
1035 (add_dot_0_if_integer ? precision-1 : precision))
1036 use_exp = 1;
1037 break;
1038 default:
1039 PyErr_BadInternalCall();
1040 goto exit;
1041 }
1042
1043 /* if using an exponent, reset decimal point position to 1 and adjust
1044 exponent accordingly.*/
1045 if (use_exp) {
1046 exp = decpt - 1;
1047 decpt = 1;
1048 }
1049 /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start <
1050 decpt < vdigits_end if add_dot_0_if_integer and no exponent */
1051 vdigits_start = decpt <= 0 ? decpt-1 : 0;
1052 if (!use_exp && add_dot_0_if_integer)
1053 vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1;
1054 else
1055 vdigits_end = vdigits_end > decpt ? vdigits_end : decpt;
1056
1057 /* double check inequalities */
1058 assert(vdigits_start <= 0 &&
1059 0 <= digits_len &&
1060 digits_len <= vdigits_end);
1061 /* decimal point should be in (vdigits_start, vdigits_end] */
1062 assert(vdigits_start < decpt && decpt <= vdigits_end);
1063
1064 /* Compute an upper bound how much memory we need. This might be a few
1065 chars too long, but no big deal. */
1066 bufsize =
1067 /* sign, decimal point and trailing 0 byte */
1068 3 +
1069
1070 /* total digit count (including zero padding on both sides) */
1071 (vdigits_end - vdigits_start) +
1072
1073 /* exponent "e+100", max 3 numerical digits */
1074 (use_exp ? 5 : 0);
1075
1076 /* Now allocate the memory and initialize p to point to the start of
1077 it. */
1078 buf = (char *)PyMem_Malloc(bufsize);
1079 if (buf == NULL) {
1080 PyErr_NoMemory();
1081 goto exit;
1082 }
1083 p = buf;
1084
1085 /* Add a negative sign if negative, and a plus sign if non-negative
1086 and always_add_sign is true. */
1087 if (sign == 1)
1088 *p++ = '-';
1089 else if (always_add_sign)
1090 *p++ = '+';
1091
1092 /* note that exactly one of the three 'if' conditions is true,
1093 so we include exactly one decimal point */
1094 /* Zero padding on left of digit string */
1095 if (decpt <= 0) {
1096 memset(p, '0', decpt-vdigits_start);
1097 p += decpt - vdigits_start;
1098 *p++ = '.';
1099 memset(p, '0', 0-decpt);
1100 p += 0-decpt;
1101 }
1102 else {
1103 memset(p, '0', 0-vdigits_start);
1104 p += 0 - vdigits_start;
1105 }
1106
1107 /* Digits, with included decimal point */
1108 if (0 < decpt && decpt <= digits_len) {
1109 strncpy(p, digits, decpt-0);
1110 p += decpt-0;
1111 *p++ = '.';
1112 strncpy(p, digits+decpt, digits_len-decpt);
1113 p += digits_len-decpt;
1114 }
1115 else {
1116 strncpy(p, digits, digits_len);
1117 p += digits_len;
1118 }
1119
1120 /* And zeros on the right */
1121 if (digits_len < decpt) {
1122 memset(p, '0', decpt-digits_len);
1123 p += decpt-digits_len;
1124 *p++ = '.';
1125 memset(p, '0', vdigits_end-decpt);
1126 p += vdigits_end-decpt;
1127 }
1128 else {
1129 memset(p, '0', vdigits_end-digits_len);
1130 p += vdigits_end-digits_len;
1131 }
1132
1133 /* Delete a trailing decimal pt unless using alternative formatting. */
1134 if (p[-1] == '.' && !use_alt_formatting)
1135 p--;
1136
1137 /* Now that we've done zero padding, add an exponent if needed. */
1138 if (use_exp) {
1139 *p++ = float_strings[OFS_E][0];
1140 exp_len = sprintf(p, "%+.02d", exp);
1141 p += exp_len;
1142 }
1143 exit:
1144 if (buf) {
1145 *p = '\0';
1146 /* It's too late if this fails, as we've already stepped on
1147 memory that isn't ours. But it's an okay debugging test. */
1148 assert(p-buf < bufsize);
1149 }
1150 if (digits)
1151 _Py_dg_freedtoa(digits);
1152
1153 return buf;
1154}
1155
1156
1157PyAPI_FUNC(char *) PyOS_double_to_string(double val,
Eric Smith193125a2009-04-16 22:08:31 +00001158 char format_code,
1159 int precision,
1160 int flags,
Eric Smith0923d1d2009-04-16 20:16:10 +00001161 int *type)
1162{
Eric Smith193125a2009-04-16 22:08:31 +00001163 char **float_strings = lc_float_strings;
1164 int mode;
Eric Smith0923d1d2009-04-16 20:16:10 +00001165
Eric Smith193125a2009-04-16 22:08:31 +00001166 /* Validate format_code, and map upper and lower case. Compute the
1167 mode and make any adjustments as needed. */
Eric Smith0923d1d2009-04-16 20:16:10 +00001168 switch (format_code) {
Eric Smith193125a2009-04-16 22:08:31 +00001169 /* exponent */
Eric Smith0923d1d2009-04-16 20:16:10 +00001170 case 'E':
Eric Smith0923d1d2009-04-16 20:16:10 +00001171 float_strings = uc_float_strings;
Eric Smith193125a2009-04-16 22:08:31 +00001172 format_code = 'e';
1173 /* Fall through. */
Eric Smith0923d1d2009-04-16 20:16:10 +00001174 case 'e':
1175 mode = 2;
1176 precision++;
1177 break;
Eric Smith193125a2009-04-16 22:08:31 +00001178
1179 /* fixed */
1180 case 'F':
1181 float_strings = uc_float_strings;
1182 format_code = 'f';
1183 /* Fall through. */
Eric Smith0923d1d2009-04-16 20:16:10 +00001184 case 'f':
1185 mode = 3;
1186 break;
Eric Smith193125a2009-04-16 22:08:31 +00001187
1188 /* general */
1189 case 'G':
1190 float_strings = uc_float_strings;
1191 format_code = 'g';
1192 /* Fall through. */
Eric Smith0923d1d2009-04-16 20:16:10 +00001193 case 'g':
1194 mode = 2;
1195 /* precision 0 makes no sense for 'g' format; interpret as 1 */
1196 if (precision == 0)
1197 precision = 1;
1198 break;
Eric Smith193125a2009-04-16 22:08:31 +00001199
1200 /* repr format */
Eric Smith0923d1d2009-04-16 20:16:10 +00001201 case 'r':
Eric Smith0923d1d2009-04-16 20:16:10 +00001202 mode = 0;
1203 /* Supplied precision is unused, must be 0. */
1204 if (precision != 0) {
1205 PyErr_BadInternalCall();
1206 return NULL;
1207 }
1208 break;
Eric Smith193125a2009-04-16 22:08:31 +00001209
1210 /* str format */
Eric Smith0923d1d2009-04-16 20:16:10 +00001211 case 's':
1212 mode = 2;
1213 /* Supplied precision is unused, must be 0. */
1214 if (precision != 0) {
1215 PyErr_BadInternalCall();
1216 return NULL;
1217 }
1218 precision = 12;
1219 break;
Eric Smith193125a2009-04-16 22:08:31 +00001220
1221 default:
1222 PyErr_BadInternalCall();
1223 return NULL;
Eric Smith0923d1d2009-04-16 20:16:10 +00001224 }
1225
Eric Smith193125a2009-04-16 22:08:31 +00001226 return format_float_short(val, format_code, mode, precision,
Eric Smith0923d1d2009-04-16 20:16:10 +00001227 flags & Py_DTSF_SIGN,
1228 flags & Py_DTSF_ADD_DOT_0,
1229 flags & Py_DTSF_ALT,
1230 float_strings, type);
1231}
1232#endif /* ifdef PY_NO_SHORT_FLOAT_REPR */