annotate Python/pystrtod.c @ 58973:db86bf39ccaa legacy-trunk

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