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