blob: 9e00823fad8993c40af3c4e66edbc07e5604e8aa [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
6/* ascii character tests (as opposed to locale tests) */
7#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
8 (c) == '\r' || (c) == '\t' || (c) == '\v')
9#define ISDIGIT(c) ((c) >= '0' && (c) <= '9')
Martin v. Löwis737ea822004-06-08 18:52:54 +000010
11
12/**
13 * PyOS_ascii_strtod:
14 * @nptr: the string to convert to a numeric value.
15 * @endptr: if non-%NULL, it returns the character after
16 * the last character used in the conversion.
17 *
18 * Converts a string to a #gdouble value.
19 * This function behaves like the standard strtod() function
20 * does in the C locale. It does this without actually
21 * changing the current locale, since that would not be
22 * thread-safe.
23 *
24 * This function is typically used when reading configuration
25 * files or other non-user input that should be locale independent.
26 * To handle input from the user you should normally use the
27 * locale-sensitive system strtod() function.
28 *
29 * If the correct value would cause overflow, plus or minus %HUGE_VAL
30 * is returned (according to the sign of the value), and %ERANGE is
31 * stored in %errno. If the correct value would cause underflow,
32 * zero is returned and %ERANGE is stored in %errno.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000033 * If memory allocation fails, %ENOMEM is stored in %errno.
Martin v. Löwis737ea822004-06-08 18:52:54 +000034 *
35 * This function resets %errno before calling strtod() so that
36 * you can reliably detect overflow and underflow.
37 *
38 * Return value: the #gdouble value.
39 **/
Eric Smith0923d1d2009-04-16 20:16:10 +000040
41#ifndef PY_NO_SHORT_FLOAT_REPR
42
43double
44PyOS_ascii_strtod(const char *nptr, char **endptr)
45{
46 double result;
47 _Py_SET_53BIT_PRECISION_HEADER;
48
49 assert(nptr != NULL);
50 /* Set errno to zero, so that we can distinguish zero results
51 and underflows */
52 errno = 0;
53
54 _Py_SET_53BIT_PRECISION_START;
55 result = _Py_dg_strtod(nptr, endptr);
56 _Py_SET_53BIT_PRECISION_END;
57
58 return result;
59
60}
61
62#else
63
64/*
65 Use system strtod; since strtod is locale aware, we may
66 have to first fix the decimal separator.
67
68 Note that unlike _Py_dg_strtod, the system strtod may not always give
69 correctly rounded results.
70*/
71
Martin v. Löwis737ea822004-06-08 18:52:54 +000072double
Neal Norwitze7214a12005-12-18 05:03:17 +000073PyOS_ascii_strtod(const char *nptr, char **endptr)
Martin v. Löwis737ea822004-06-08 18:52:54 +000074{
75 char *fail_pos;
Neal Norwitz0e7a0ed2005-12-18 05:37:36 +000076 double val = -1.0;
Martin v. Löwis737ea822004-06-08 18:52:54 +000077 struct lconv *locale_data;
78 const char *decimal_point;
Neal Norwitzd39d8612006-01-08 01:03:36 +000079 size_t decimal_point_len;
Martin v. Löwis737ea822004-06-08 18:52:54 +000080 const char *p, *decimal_point_pos;
81 const char *end = NULL; /* Silence gcc */
Christian Heimesfaf2f632008-01-06 16:59:19 +000082 const char *digits_pos = NULL;
83 int negate = 0;
Martin v. Löwis737ea822004-06-08 18:52:54 +000084
Martin v. Löwis737ea822004-06-08 18:52:54 +000085 assert(nptr != NULL);
86
87 fail_pos = NULL;
88
89 locale_data = localeconv();
90 decimal_point = locale_data->decimal_point;
91 decimal_point_len = strlen(decimal_point);
92
93 assert(decimal_point_len != 0);
94
95 decimal_point_pos = NULL;
Christian Heimesfaf2f632008-01-06 16:59:19 +000096
97 /* We process any leading whitespace and the optional sign manually,
98 then pass the remainder to the system strtod. This ensures that
99 the result of an underflow has the correct sign. (bug #1725) */
100
101 p = nptr;
102 /* Skip leading space */
103 while (ISSPACE(*p))
104 p++;
105
106 /* Process leading sign, if present */
107 if (*p == '-') {
108 negate = 1;
109 p++;
110 } else if (*p == '+') {
111 p++;
112 }
113
114 /* What's left should begin with a digit, a decimal point, or one of
115 the letters i, I, n, N. It should not begin with 0x or 0X */
116 if ((!ISDIGIT(*p) &&
117 *p != '.' && *p != 'i' && *p != 'I' && *p != 'n' && *p != 'N')
118 ||
119 (*p == '0' && (p[1] == 'x' || p[1] == 'X')))
120 {
121 if (endptr)
122 *endptr = (char*)nptr;
123 errno = EINVAL;
124 return val;
125 }
126 digits_pos = p;
127
Martin v. Löwis737ea822004-06-08 18:52:54 +0000128 if (decimal_point[0] != '.' ||
129 decimal_point[1] != 0)
130 {
Neal Norwitze7214a12005-12-18 05:03:17 +0000131 while (ISDIGIT(*p))
132 p++;
133
134 if (*p == '.')
Martin v. Löwis737ea822004-06-08 18:52:54 +0000135 {
Neal Norwitze7214a12005-12-18 05:03:17 +0000136 decimal_point_pos = p++;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000137
Martin v. Löwis737ea822004-06-08 18:52:54 +0000138 while (ISDIGIT(*p))
139 p++;
140
Neal Norwitze7214a12005-12-18 05:03:17 +0000141 if (*p == 'e' || *p == 'E')
142 p++;
143 if (*p == '+' || *p == '-')
144 p++;
145 while (ISDIGIT(*p))
146 p++;
147 end = p;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000148 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000149 else if (strncmp(p, decimal_point, decimal_point_len) == 0)
150 {
151 /* Python bug #1417699 */
Christian Heimesfaf2f632008-01-06 16:59:19 +0000152 if (endptr)
153 *endptr = (char*)nptr;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000154 errno = EINVAL;
155 return val;
156 }
Christian Heimesb186d002008-03-18 15:15:01 +0000157 /* For the other cases, we need not convert the decimal
158 point */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000159 }
160
Neal Norwitze7214a12005-12-18 05:03:17 +0000161 /* Set errno to zero, so that we can distinguish zero results
162 and underflows */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000163 errno = 0;
164
165 if (decimal_point_pos)
166 {
167 char *copy, *c;
168
Christian Heimesb186d002008-03-18 15:15:01 +0000169 /* We need to convert the '.' to the locale specific decimal
170 point */
Christian Heimesfaf2f632008-01-06 16:59:19 +0000171 copy = (char *)PyMem_MALLOC(end - digits_pos +
172 1 + decimal_point_len);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000173 if (copy == NULL) {
174 if (endptr)
175 *endptr = (char *)nptr;
176 errno = ENOMEM;
177 return val;
178 }
Martin v. Löwis737ea822004-06-08 18:52:54 +0000179
180 c = copy;
Christian Heimesfaf2f632008-01-06 16:59:19 +0000181 memcpy(c, digits_pos, decimal_point_pos - digits_pos);
182 c += decimal_point_pos - digits_pos;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000183 memcpy(c, decimal_point, decimal_point_len);
184 c += decimal_point_len;
Christian Heimesb186d002008-03-18 15:15:01 +0000185 memcpy(c, decimal_point_pos + 1,
186 end - (decimal_point_pos + 1));
Martin v. Löwis737ea822004-06-08 18:52:54 +0000187 c += end - (decimal_point_pos + 1);
188 *c = 0;
189
190 val = strtod(copy, &fail_pos);
191
192 if (fail_pos)
193 {
194 if (fail_pos > decimal_point_pos)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000195 fail_pos = (char *)digits_pos +
196 (fail_pos - copy) -
197 (decimal_point_len - 1);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000198 else
Christian Heimesfaf2f632008-01-06 16:59:19 +0000199 fail_pos = (char *)digits_pos +
200 (fail_pos - copy);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000201 }
202
Thomas Wouters477c8d52006-05-27 19:21:47 +0000203 PyMem_FREE(copy);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000204
205 }
Neal Norwitze7214a12005-12-18 05:03:17 +0000206 else {
Christian Heimesfaf2f632008-01-06 16:59:19 +0000207 val = strtod(digits_pos, &fail_pos);
Neal Norwitze7214a12005-12-18 05:03:17 +0000208 }
Martin v. Löwis737ea822004-06-08 18:52:54 +0000209
Christian Heimesfaf2f632008-01-06 16:59:19 +0000210 if (fail_pos == digits_pos)
211 fail_pos = (char *)nptr;
212
213 if (negate && fail_pos != nptr)
214 val = -val;
215
Martin v. Löwis737ea822004-06-08 18:52:54 +0000216 if (endptr)
217 *endptr = fail_pos;
218
219 return val;
220}
221
Eric Smith0923d1d2009-04-16 20:16:10 +0000222#endif
223
224double
225PyOS_ascii_atof(const char *nptr)
226{
227 return PyOS_ascii_strtod(nptr, NULL);
228}
229
230
Eric Smithb2c7af82008-04-30 02:12:09 +0000231/* Given a string that may have a decimal point in the current
232 locale, change it back to a dot. Since the string cannot get
233 longer, no need for a maximum buffer size parameter. */
234Py_LOCAL_INLINE(void)
235change_decimal_from_locale_to_dot(char* buffer)
236{
237 struct lconv *locale_data = localeconv();
238 const char *decimal_point = locale_data->decimal_point;
239
240 if (decimal_point[0] != '.' || decimal_point[1] != 0) {
241 size_t decimal_point_len = strlen(decimal_point);
242
243 if (*buffer == '+' || *buffer == '-')
244 buffer++;
245 while (isdigit(Py_CHARMASK(*buffer)))
246 buffer++;
247 if (strncmp(buffer, decimal_point, decimal_point_len) == 0) {
248 *buffer = '.';
249 buffer++;
250 if (decimal_point_len > 1) {
251 /* buffer needs to get smaller */
252 size_t rest_len = strlen(buffer +
253 (decimal_point_len - 1));
254 memmove(buffer,
255 buffer + (decimal_point_len - 1),
256 rest_len);
257 buffer[rest_len] = 0;
258 }
259 }
260 }
261}
262
Martin v. Löwis737ea822004-06-08 18:52:54 +0000263
Christian Heimesc3f30c42008-02-22 16:37:40 +0000264/* From the C99 standard, section 7.19.6:
265The exponent always contains at least two digits, and only as many more digits
266as necessary to represent the exponent.
267*/
268#define MIN_EXPONENT_DIGITS 2
269
Eric Smithb2c7af82008-04-30 02:12:09 +0000270/* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS
271 in length. */
272Py_LOCAL_INLINE(void)
273ensure_minumim_exponent_length(char* buffer, size_t buf_size)
274{
275 char *p = strpbrk(buffer, "eE");
276 if (p && (*(p + 1) == '-' || *(p + 1) == '+')) {
277 char *start = p + 2;
278 int exponent_digit_cnt = 0;
279 int leading_zero_cnt = 0;
280 int in_leading_zeros = 1;
281 int significant_digit_cnt;
282
283 /* Skip over the exponent and the sign. */
284 p += 2;
285
286 /* Find the end of the exponent, keeping track of leading
287 zeros. */
288 while (*p && isdigit(Py_CHARMASK(*p))) {
289 if (in_leading_zeros && *p == '0')
290 ++leading_zero_cnt;
291 if (*p != '0')
292 in_leading_zeros = 0;
293 ++p;
294 ++exponent_digit_cnt;
295 }
296
297 significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt;
298 if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) {
299 /* If there are 2 exactly digits, we're done,
300 regardless of what they contain */
301 }
302 else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) {
303 int extra_zeros_cnt;
304
305 /* There are more than 2 digits in the exponent. See
306 if we can delete some of the leading zeros */
307 if (significant_digit_cnt < MIN_EXPONENT_DIGITS)
308 significant_digit_cnt = MIN_EXPONENT_DIGITS;
309 extra_zeros_cnt = exponent_digit_cnt -
310 significant_digit_cnt;
311
312 /* Delete extra_zeros_cnt worth of characters from the
313 front of the exponent */
314 assert(extra_zeros_cnt >= 0);
315
316 /* Add one to significant_digit_cnt to copy the
317 trailing 0 byte, thus setting the length */
318 memmove(start,
319 start + extra_zeros_cnt,
320 significant_digit_cnt + 1);
321 }
322 else {
323 /* If there are fewer than 2 digits, add zeros
324 until there are 2, if there's enough room */
325 int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt;
326 if (start + zeros + exponent_digit_cnt + 1
327 < buffer + buf_size) {
328 memmove(start + zeros, start,
329 exponent_digit_cnt + 1);
330 memset(start, '0', zeros);
331 }
332 }
333 }
334}
335
Eric Smith0923d1d2009-04-16 20:16:10 +0000336/* Ensure that buffer has a decimal point in it. The decimal point will not
337 be in the current locale, it will always be '.'. Don't add a decimal if an
338 exponent is present. */
Eric Smithb2c7af82008-04-30 02:12:09 +0000339Py_LOCAL_INLINE(void)
340ensure_decimal_point(char* buffer, size_t buf_size)
341{
342 int insert_count = 0;
343 char* chars_to_insert;
344
345 /* search for the first non-digit character */
346 char *p = buffer;
Eric Smith2ad79e82008-07-19 00:33:23 +0000347 if (*p == '-' || *p == '+')
348 /* Skip leading sign, if present. I think this could only
349 ever be '-', but it can't hurt to check for both. */
350 ++p;
Eric Smithb2c7af82008-04-30 02:12:09 +0000351 while (*p && isdigit(Py_CHARMASK(*p)))
352 ++p;
353
354 if (*p == '.') {
355 if (isdigit(Py_CHARMASK(*(p+1)))) {
356 /* Nothing to do, we already have a decimal
357 point and a digit after it */
358 }
359 else {
360 /* We have a decimal point, but no following
361 digit. Insert a zero after the decimal. */
362 ++p;
363 chars_to_insert = "0";
364 insert_count = 1;
365 }
366 }
Eric Smith0923d1d2009-04-16 20:16:10 +0000367 else if (!(*p == 'e' || *p == 'E')) {
368 /* Don't add ".0" if we have an exponent. */
Eric Smithb2c7af82008-04-30 02:12:09 +0000369 chars_to_insert = ".0";
370 insert_count = 2;
371 }
372 if (insert_count) {
373 size_t buf_len = strlen(buffer);
374 if (buf_len + insert_count + 1 >= buf_size) {
375 /* If there is not enough room in the buffer
376 for the additional text, just skip it. It's
377 not worth generating an error over. */
378 }
379 else {
380 memmove(p + insert_count, p,
381 buffer + strlen(buffer) - p + 1);
382 memcpy(p, chars_to_insert, insert_count);
383 }
384 }
385}
386
Christian Heimesc3f30c42008-02-22 16:37:40 +0000387/* see FORMATBUFLEN in unicodeobject.c */
388#define FLOAT_FORMATBUFLEN 120
389
Martin v. Löwis737ea822004-06-08 18:52:54 +0000390/**
391 * PyOS_ascii_formatd:
392 * @buffer: A buffer to place the resulting string in
Christian Heimesb186d002008-03-18 15:15:01 +0000393 * @buf_size: The length of the buffer.
Martin v. Löwis737ea822004-06-08 18:52:54 +0000394 * @format: The printf()-style format to use for the
395 * code to use for converting.
396 * @d: The #gdouble to convert
397 *
398 * Converts a #gdouble to a string, using the '.' as
399 * decimal point. To format the number you pass in
400 * a printf()-style format string. Allowed conversion
Eric Smith0923d1d2009-04-16 20:16:10 +0000401 * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'.
Martin v. Löwis737ea822004-06-08 18:52:54 +0000402 *
Christian Heimesb186d002008-03-18 15:15:01 +0000403 * 'Z' is the same as 'g', except it always has a decimal and
404 * at least one digit after the decimal.
Christian Heimesc3f30c42008-02-22 16:37:40 +0000405 *
Martin v. Löwis737ea822004-06-08 18:52:54 +0000406 * Return value: The pointer to the buffer with the converted string.
407 **/
408char *
409PyOS_ascii_formatd(char *buffer,
Christian Heimesb186d002008-03-18 15:15:01 +0000410 size_t buf_size,
Martin v. Löwis737ea822004-06-08 18:52:54 +0000411 const char *format,
412 double d)
413{
Martin v. Löwis737ea822004-06-08 18:52:54 +0000414 char format_char;
Christian Heimesc3f30c42008-02-22 16:37:40 +0000415 size_t format_len = strlen(format);
416
Christian Heimesb186d002008-03-18 15:15:01 +0000417 /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but
418 also with at least one character past the decimal. */
Christian Heimesc3f30c42008-02-22 16:37:40 +0000419 char tmp_format[FLOAT_FORMATBUFLEN];
Martin v. Löwis737ea822004-06-08 18:52:54 +0000420
Christian Heimesc3f30c42008-02-22 16:37:40 +0000421 /* The last character in the format string must be the format char */
422 format_char = format[format_len - 1];
Martin v. Löwis737ea822004-06-08 18:52:54 +0000423
Martin v. Löwis737ea822004-06-08 18:52:54 +0000424 if (format[0] != '%')
425 return NULL;
426
Christian Heimesc3f30c42008-02-22 16:37:40 +0000427 /* I'm not sure why this test is here. It's ensuring that the format
428 string after the first character doesn't have a single quote, a
429 lowercase l, or a percent. This is the reverse of the commented-out
430 test about 10 lines ago. */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000431 if (strpbrk(format + 1, "'l%"))
432 return NULL;
433
Christian Heimesb186d002008-03-18 15:15:01 +0000434 /* Also curious about this function is that it accepts format strings
435 like "%xg", which are invalid for floats. In general, the
436 interface to this function is not very good, but changing it is
437 difficult because it's a public API. */
438
Martin v. Löwis737ea822004-06-08 18:52:54 +0000439 if (!(format_char == 'e' || format_char == 'E' ||
440 format_char == 'f' || format_char == 'F' ||
Christian Heimesc3f30c42008-02-22 16:37:40 +0000441 format_char == 'g' || format_char == 'G' ||
Eric Smith0923d1d2009-04-16 20:16:10 +0000442 format_char == 'Z'))
Martin v. Löwis737ea822004-06-08 18:52:54 +0000443 return NULL;
444
Eric Smith0923d1d2009-04-16 20:16:10 +0000445 /* Map 'Z' format_char to 'g', by copying the format string and
Christian Heimesb186d002008-03-18 15:15:01 +0000446 replacing the final char with a 'g' */
Eric Smith0923d1d2009-04-16 20:16:10 +0000447 if (format_char == 'Z') {
Christian Heimesc3f30c42008-02-22 16:37:40 +0000448 if (format_len + 1 >= sizeof(tmp_format)) {
449 /* The format won't fit in our copy. Error out. In
Christian Heimesb186d002008-03-18 15:15:01 +0000450 practice, this will never happen and will be
451 detected by returning NULL */
Christian Heimesc3f30c42008-02-22 16:37:40 +0000452 return NULL;
453 }
454 strcpy(tmp_format, format);
455 tmp_format[format_len - 1] = 'g';
456 format = tmp_format;
457 }
Martin v. Löwis737ea822004-06-08 18:52:54 +0000458
Christian Heimesb186d002008-03-18 15:15:01 +0000459
Christian Heimesc3f30c42008-02-22 16:37:40 +0000460 /* Have PyOS_snprintf do the hard work */
Christian Heimesb186d002008-03-18 15:15:01 +0000461 PyOS_snprintf(buffer, buf_size, format, d);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000462
Eric Smithb2c7af82008-04-30 02:12:09 +0000463 /* Do various fixups on the return string */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000464
Eric Smithb2c7af82008-04-30 02:12:09 +0000465 /* Get the current locale, and find the decimal point string.
Eric Smith0923d1d2009-04-16 20:16:10 +0000466 Convert that string back to a dot. */
467 change_decimal_from_locale_to_dot(buffer);
Christian Heimesc3f30c42008-02-22 16:37:40 +0000468
469 /* If an exponent exists, ensure that the exponent is at least
470 MIN_EXPONENT_DIGITS digits, providing the buffer is large enough
471 for the extra zeros. Also, if there are more than
472 MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get
473 back to MIN_EXPONENT_DIGITS */
Eric Smithb2c7af82008-04-30 02:12:09 +0000474 ensure_minumim_exponent_length(buffer, buf_size);
Martin v. Löwis737ea822004-06-08 18:52:54 +0000475
Christian Heimesb186d002008-03-18 15:15:01 +0000476 /* If format_char is 'Z', make sure we have at least one character
477 after the decimal point (and make sure we have a decimal point). */
Eric Smithb2c7af82008-04-30 02:12:09 +0000478 if (format_char == 'Z')
479 ensure_decimal_point(buffer, buf_size);
Christian Heimesb186d002008-03-18 15:15:01 +0000480
Martin v. Löwis737ea822004-06-08 18:52:54 +0000481 return buffer;
482}
483
Eric Smith0923d1d2009-04-16 20:16:10 +0000484#ifdef PY_NO_SHORT_FLOAT_REPR
485
486/* The fallback code to use if _Py_dg_dtoa is not available. */
487
488PyAPI_FUNC(char *) PyOS_double_to_string(double val,
489 char format_code,
490 int precision,
491 int flags,
492 int *type)
Martin v. Löwis737ea822004-06-08 18:52:54 +0000493{
Eric Smith0923d1d2009-04-16 20:16:10 +0000494 char buf[128];
495 char format[32];
496 Py_ssize_t len;
497 char *result;
498 char *p;
499 int t;
500 int upper = 0;
501
502 /* Validate format_code, and map upper and lower case */
503 switch (format_code) {
504 case 'e': /* exponent */
505 case 'f': /* fixed */
506 case 'g': /* general */
507 break;
508 case 'E':
509 upper = 1;
510 format_code = 'e';
511 break;
512 case 'F':
513 upper = 1;
514 format_code = 'f';
515 break;
516 case 'G':
517 upper = 1;
518 format_code = 'g';
519 break;
520 case 'r': /* repr format */
521 /* Supplied precision is unused, must be 0. */
522 if (precision != 0) {
523 PyErr_BadInternalCall();
524 return NULL;
525 }
526 precision = 17;
527 format_code = 'g';
528 break;
529 case 's': /* str format */
530 /* Supplied precision is unused, must be 0. */
531 if (precision != 0) {
532 PyErr_BadInternalCall();
533 return NULL;
534 }
535 precision = 12;
536 format_code = 'g';
537 break;
538 default:
539 PyErr_BadInternalCall();
540 return NULL;
541 }
542
543 /* Handle nan and inf. */
544 if (Py_IS_NAN(val)) {
545 strcpy(buf, "nan");
546 t = Py_DTST_NAN;
547 } else if (Py_IS_INFINITY(val)) {
548 if (copysign(1., val) == 1.)
549 strcpy(buf, "inf");
550 else
551 strcpy(buf, "-inf");
552 t = Py_DTST_INFINITE;
553 } else {
554 t = Py_DTST_FINITE;
555
556
557 if (flags & Py_DTSF_ADD_DOT_0)
558 format_code = 'Z';
559
560 PyOS_snprintf(format, 32, "%%%s.%i%c", (flags & Py_DTSF_ALT ? "#" : ""), precision, format_code);
561 PyOS_ascii_formatd(buf, sizeof(buf), format, val);
562 }
563
564 len = strlen(buf);
565
566 /* Add 1 for the trailing 0 byte.
567 Add 1 because we might need to make room for the sign.
568 */
569 result = PyMem_Malloc(len + 2);
570 if (result == NULL) {
571 PyErr_NoMemory();
572 return NULL;
573 }
574 p = result;
575
576 /* Never add sign for nan/inf, even if asked. */
577 if (flags & Py_DTSF_SIGN && buf[0] != '-' && t == Py_DTST_FINITE)
578 *p++ = '+';
579
580 strcpy(p, buf);
581
582 if (upper) {
583 /* Convert to upper case. */
584 char *p1;
585 for (p1 = p; *p1; p1++)
586 *p1 = toupper(*p1);
587 }
588
589 if (type)
590 *type = t;
591 return result;
Martin v. Löwis737ea822004-06-08 18:52:54 +0000592}
Eric Smith0923d1d2009-04-16 20:16:10 +0000593
594#else
595
596/* _Py_dg_dtoa is available. */
597
598/* I'm using a lookup table here so that I don't have to invent a non-locale
599 specific way to convert to uppercase */
600#define OFS_INF 0
601#define OFS_NAN 1
602#define OFS_E 2
603
604/* The lengths of these are known to the code below, so don't change them */
605static char *lc_float_strings[] = {
606 "inf",
607 "nan",
608 "e",
609};
610static char *uc_float_strings[] = {
611 "INF",
612 "NAN",
613 "E",
614};
615
616
617/* Convert a double d to a string, and return a PyMem_Malloc'd block of
618 memory contain the resulting string.
619
620 Arguments:
621 d is the double to be converted
622 format_code is one of 'e', 'f', 'g', 'r' or 's'. 'e', 'f' and 'g'
623 correspond to '%e', '%f' and '%g'; 'r' and 's' correspond
624 to repr and str.
625 mode is one of '0', '2' or '3', and is completely determined by
626 format_code: 'e', 'g' and 's' use mode 2; 'f' mode 3, 'r' mode 0.
627 precision is the desired precision
628 always_add_sign is nonzero if a '+' sign should be included for positive
629 numbers
630 add_dot_0_if_integer is nonzero if integers in non-exponential form
631 should have ".0" added. Only applies to format codes 'r', 's', and 'g'.
632 use_alt_formatting is nonzero if alternative formatting should be
633 used. Only applies to format codes 'e', 'f' and 'g'.
634 type, if non-NULL, will be set to one of these constants to identify
635 the type of the 'd' argument:
636 Py_DTST_FINITE
637 Py_DTST_INFINITE
638 Py_DTST_NAN
639
640 Returns a PyMem_Malloc'd block of memory containing the resulting string,
641 or NULL on error. If NULL is returned, the Python error has been set.
642 */
643
644static char *
645format_float_short(double d, char format_code,
646 int mode, Py_ssize_t precision,
647 int always_add_sign, int add_dot_0_if_integer,
648 int use_alt_formatting, char **float_strings, int *type)
649{
650 char *buf = NULL;
651 char *p = NULL;
652 Py_ssize_t bufsize = 0;
653 char *digits, *digits_end;
654 int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0;
655 Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end;
656 _Py_SET_53BIT_PRECISION_HEADER;
657
658 /* _Py_dg_dtoa returns a digit string (no decimal point or exponent).
659 Must be matched by a call to _Py_dg_freedtoa. */
660 _Py_SET_53BIT_PRECISION_START;
661 digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign,
662 &digits_end);
663 _Py_SET_53BIT_PRECISION_END;
664
665 decpt = (Py_ssize_t)decpt_as_int;
666 if (digits == NULL) {
667 /* The only failure mode is no memory. */
668 PyErr_NoMemory();
669 goto exit;
670 }
671 assert(digits_end != NULL && digits_end >= digits);
672 digits_len = digits_end - digits;
673
674 if (digits_len && !isdigit(digits[0])) {
675 /* Infinities and nans here; adapt Gay's output,
676 so convert Infinity to inf and NaN to nan, and
677 ignore sign of nan. Then return. */
678
679 /* We only need 5 bytes to hold the result "+inf\0" . */
680 bufsize = 5; /* Used later in an assert. */
681 buf = (char *)PyMem_Malloc(bufsize);
682 if (buf == NULL) {
683 PyErr_NoMemory();
684 goto exit;
685 }
686 p = buf;
687
688 if (digits[0] == 'i' || digits[0] == 'I') {
689 if (sign == 1) {
690 *p++ = '-';
691 }
692 else if (always_add_sign) {
693 *p++ = '+';
694 }
695 strncpy(p, float_strings[OFS_INF], 3);
696 p += 3;
697
698 if (type)
699 *type = Py_DTST_INFINITE;
700 }
701 else if (digits[0] == 'n' || digits[0] == 'N') {
702 /* note that we *never* add a sign for a nan,
703 even if one has explicitly been requested */
704 strncpy(p, float_strings[OFS_NAN], 3);
705 p += 3;
706
707 if (type)
708 *type = Py_DTST_NAN;
709 }
710 else {
711 /* shouldn't get here: Gay's code should always return
712 something starting with a digit, an 'I', or 'N' */
713 strncpy(p, "ERR", 3);
714 p += 3;
715 assert(0);
716 }
717 goto exit;
718 }
719
720 /* The result must be finite (not inf or nan). */
721 if (type)
722 *type = Py_DTST_FINITE;
723
724
725 /* We got digits back, format them. We may need to pad 'digits'
726 either on the left or right (or both) with extra zeros, so in
727 general the resulting string has the form
728
729 [<sign>]<zeros><digits><zeros>[<exponent>]
730
731 where either of the <zeros> pieces could be empty, and there's a
732 decimal point that could appear either in <digits> or in the
733 leading or trailing <zeros>.
734
735 Imagine an infinite 'virtual' string vdigits, consisting of the
736 string 'digits' (starting at index 0) padded on both the left and
737 right with infinite strings of zeros. We want to output a slice
738
739 vdigits[vdigits_start : vdigits_end]
740
741 of this virtual string. Thus if vdigits_start < 0 then we'll end
742 up producing some leading zeros; if vdigits_end > digits_len there
743 will be trailing zeros in the output. The next section of code
744 determines whether to use an exponent or not, figures out the
745 position 'decpt' of the decimal point, and computes 'vdigits_start'
746 and 'vdigits_end'. */
747 vdigits_end = digits_len;
748 switch (format_code) {
749 case 'e':
750 use_exp = 1;
751 vdigits_end = precision;
752 break;
753 case 'f':
754 vdigits_end = decpt + precision;
755 break;
756 case 'g':
757 if (decpt <= -4 || decpt > precision)
758 use_exp = 1;
759 if (use_alt_formatting)
760 vdigits_end = precision;
761 break;
762 case 'r':
763 /* convert to exponential format at 1e16. We used to convert
764 at 1e17, but that gives odd-looking results for some values
765 when a 16-digit 'shortest' repr is padded with bogus zeros.
766 For example, repr(2e16+8) would give 20000000000000010.0;
767 the true value is 20000000000000008.0. */
768 if (decpt <= -4 || decpt > 16)
769 use_exp = 1;
770 break;
771 case 's':
772 /* if we're forcing a digit after the point, convert to
773 exponential format at 1e11. If not, convert at 1e12. */
774 if (decpt <= -4 || decpt >
775 (add_dot_0_if_integer ? precision-1 : precision))
776 use_exp = 1;
777 break;
778 default:
779 PyErr_BadInternalCall();
780 goto exit;
781 }
782
783 /* if using an exponent, reset decimal point position to 1 and adjust
784 exponent accordingly.*/
785 if (use_exp) {
786 exp = decpt - 1;
787 decpt = 1;
788 }
789 /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start <
790 decpt < vdigits_end if add_dot_0_if_integer and no exponent */
791 vdigits_start = decpt <= 0 ? decpt-1 : 0;
792 if (!use_exp && add_dot_0_if_integer)
793 vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1;
794 else
795 vdigits_end = vdigits_end > decpt ? vdigits_end : decpt;
796
797 /* double check inequalities */
798 assert(vdigits_start <= 0 &&
799 0 <= digits_len &&
800 digits_len <= vdigits_end);
801 /* decimal point should be in (vdigits_start, vdigits_end] */
802 assert(vdigits_start < decpt && decpt <= vdigits_end);
803
804 /* Compute an upper bound how much memory we need. This might be a few
805 chars too long, but no big deal. */
806 bufsize =
807 /* sign, decimal point and trailing 0 byte */
808 3 +
809
810 /* total digit count (including zero padding on both sides) */
811 (vdigits_end - vdigits_start) +
812
813 /* exponent "e+100", max 3 numerical digits */
814 (use_exp ? 5 : 0);
815
816 /* Now allocate the memory and initialize p to point to the start of
817 it. */
818 buf = (char *)PyMem_Malloc(bufsize);
819 if (buf == NULL) {
820 PyErr_NoMemory();
821 goto exit;
822 }
823 p = buf;
824
825 /* Add a negative sign if negative, and a plus sign if non-negative
826 and always_add_sign is true. */
827 if (sign == 1)
828 *p++ = '-';
829 else if (always_add_sign)
830 *p++ = '+';
831
832 /* note that exactly one of the three 'if' conditions is true,
833 so we include exactly one decimal point */
834 /* Zero padding on left of digit string */
835 if (decpt <= 0) {
836 memset(p, '0', decpt-vdigits_start);
837 p += decpt - vdigits_start;
838 *p++ = '.';
839 memset(p, '0', 0-decpt);
840 p += 0-decpt;
841 }
842 else {
843 memset(p, '0', 0-vdigits_start);
844 p += 0 - vdigits_start;
845 }
846
847 /* Digits, with included decimal point */
848 if (0 < decpt && decpt <= digits_len) {
849 strncpy(p, digits, decpt-0);
850 p += decpt-0;
851 *p++ = '.';
852 strncpy(p, digits+decpt, digits_len-decpt);
853 p += digits_len-decpt;
854 }
855 else {
856 strncpy(p, digits, digits_len);
857 p += digits_len;
858 }
859
860 /* And zeros on the right */
861 if (digits_len < decpt) {
862 memset(p, '0', decpt-digits_len);
863 p += decpt-digits_len;
864 *p++ = '.';
865 memset(p, '0', vdigits_end-decpt);
866 p += vdigits_end-decpt;
867 }
868 else {
869 memset(p, '0', vdigits_end-digits_len);
870 p += vdigits_end-digits_len;
871 }
872
873 /* Delete a trailing decimal pt unless using alternative formatting. */
874 if (p[-1] == '.' && !use_alt_formatting)
875 p--;
876
877 /* Now that we've done zero padding, add an exponent if needed. */
878 if (use_exp) {
879 *p++ = float_strings[OFS_E][0];
880 exp_len = sprintf(p, "%+.02d", exp);
881 p += exp_len;
882 }
883 exit:
884 if (buf) {
885 *p = '\0';
886 /* It's too late if this fails, as we've already stepped on
887 memory that isn't ours. But it's an okay debugging test. */
888 assert(p-buf < bufsize);
889 }
890 if (digits)
891 _Py_dg_freedtoa(digits);
892
893 return buf;
894}
895
896
897PyAPI_FUNC(char *) PyOS_double_to_string(double val,
Eric Smith193125a2009-04-16 22:08:31 +0000898 char format_code,
899 int precision,
900 int flags,
Eric Smith0923d1d2009-04-16 20:16:10 +0000901 int *type)
902{
Eric Smith193125a2009-04-16 22:08:31 +0000903 char **float_strings = lc_float_strings;
904 int mode;
Eric Smith0923d1d2009-04-16 20:16:10 +0000905
Eric Smith193125a2009-04-16 22:08:31 +0000906 /* Validate format_code, and map upper and lower case. Compute the
907 mode and make any adjustments as needed. */
Eric Smith0923d1d2009-04-16 20:16:10 +0000908 switch (format_code) {
Eric Smith193125a2009-04-16 22:08:31 +0000909 /* exponent */
Eric Smith0923d1d2009-04-16 20:16:10 +0000910 case 'E':
Eric Smith0923d1d2009-04-16 20:16:10 +0000911 float_strings = uc_float_strings;
Eric Smith193125a2009-04-16 22:08:31 +0000912 format_code = 'e';
913 /* Fall through. */
Eric Smith0923d1d2009-04-16 20:16:10 +0000914 case 'e':
915 mode = 2;
916 precision++;
917 break;
Eric Smith193125a2009-04-16 22:08:31 +0000918
919 /* fixed */
920 case 'F':
921 float_strings = uc_float_strings;
922 format_code = 'f';
923 /* Fall through. */
Eric Smith0923d1d2009-04-16 20:16:10 +0000924 case 'f':
925 mode = 3;
926 break;
Eric Smith193125a2009-04-16 22:08:31 +0000927
928 /* general */
929 case 'G':
930 float_strings = uc_float_strings;
931 format_code = 'g';
932 /* Fall through. */
Eric Smith0923d1d2009-04-16 20:16:10 +0000933 case 'g':
934 mode = 2;
935 /* precision 0 makes no sense for 'g' format; interpret as 1 */
936 if (precision == 0)
937 precision = 1;
938 break;
Eric Smith193125a2009-04-16 22:08:31 +0000939
940 /* repr format */
Eric Smith0923d1d2009-04-16 20:16:10 +0000941 case 'r':
Eric Smith0923d1d2009-04-16 20:16:10 +0000942 mode = 0;
943 /* Supplied precision is unused, must be 0. */
944 if (precision != 0) {
945 PyErr_BadInternalCall();
946 return NULL;
947 }
948 break;
Eric Smith193125a2009-04-16 22:08:31 +0000949
950 /* str format */
Eric Smith0923d1d2009-04-16 20:16:10 +0000951 case 's':
952 mode = 2;
953 /* Supplied precision is unused, must be 0. */
954 if (precision != 0) {
955 PyErr_BadInternalCall();
956 return NULL;
957 }
958 precision = 12;
959 break;
Eric Smith193125a2009-04-16 22:08:31 +0000960
961 default:
962 PyErr_BadInternalCall();
963 return NULL;
Eric Smith0923d1d2009-04-16 20:16:10 +0000964 }
965
Eric Smith193125a2009-04-16 22:08:31 +0000966 return format_float_short(val, format_code, mode, precision,
Eric Smith0923d1d2009-04-16 20:16:10 +0000967 flags & Py_DTSF_SIGN,
968 flags & Py_DTSF_ADD_DOT_0,
969 flags & Py_DTSF_ALT,
970 float_strings, type);
971}
972#endif /* ifdef PY_NO_SHORT_FLOAT_REPR */