Mercurial > cpython-lru_cache-weakref
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 |
| 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 | 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 */ |
