Mercurial > cpython-lru_cache-weakref
annotate Python/pystrtod.c @ 76451:ea46ebba8a0f
Issue #13959: Re-implement imp.source_from_cache() in Lib/imp.py.
| author | Brett Cannon <brett@python.org> |
|---|---|
| date | Sat, 21 Apr 2012 18:52:52 -0400 |
| parents | b39270c6b8d1 |
| children | c468511fc887 |
| 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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
12 while(*t && Py_TOLOWER(*s) == *t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
13 s++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
14 t++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
15 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
28 double retval; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
29 const char *s; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
32 s = p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
33 if (*s == '-') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
34 negate = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
35 s++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
36 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
37 else if (*s == '+') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
38 s++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
39 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
40 if (case_insensitive_match(s, "inf")) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
41 s += 3; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
42 if (case_insensitive_match(s, "inity")) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
43 s += 5; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
44 retval = negate ? -Py_HUGE_VAL : Py_HUGE_VAL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
47 else if (case_insensitive_match(s, "nan")) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
48 s += 3; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
49 retval = negate ? -Py_NAN : Py_NAN; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
52 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
53 s = p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
54 retval = -1.0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
55 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
56 *endptr = (char *)s; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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. |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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. |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
94 double result; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
97 assert(nptr != NULL); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
98 /* Set errno to zero, so that we can distinguish zero results |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
99 and underflows */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
102 _Py_SET_53BIT_PRECISION_START; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
103 result = _Py_dg_strtod(nptr, endptr); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
106 if (*endptr == nptr) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
107 /* string might represent an inf or nan */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
127 char *fail_pos; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
128 double val = -1.0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
129 struct lconv *locale_data; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
130 const char *decimal_point; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
131 size_t decimal_point_len; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
132 const char *p, *decimal_point_pos; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
133 const char *end = NULL; /* Silence gcc */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
134 const char *digits_pos = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
141 locale_data = localeconv(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
142 decimal_point = locale_data->decimal_point; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
149 /* Parse infinities and nans */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
150 val = _Py_parse_inf_or_nan(nptr, endptr); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
151 if (*endptr != nptr) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
154 /* Set errno to zero, so that we can distinguish zero results |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
155 and underflows */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
156 errno = 0; |
|
53468
f76572108dd7
Internal plumbing changes for float parsing:
Mark Dickinson <dickinsm@gmail.com>
parents:
53332
diff
changeset
|
157 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
158 /* We process the optional sign manually, then pass the remainder to |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
159 the system strtod. This ensures that the result of an underflow |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
160 has the correct sign. (bug #1725) */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
161 p = nptr; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
162 /* Process leading sign, if present */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
163 if (*p == '-') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
164 negate = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
165 p++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
166 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
167 else if (*p == '+') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
168 p++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
169 } |
|
44535
420fe6d7d5f4
Merged revisions 59703-59773 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
39442
diff
changeset
|
170 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
171 /* Some platform strtods accept hex floats; Python shouldn't (at the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
172 moment), so we check explicitly for strings starting with '0x'. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
173 if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
174 goto invalid_string; |
|
53468
f76572108dd7
Internal plumbing changes for float parsing:
Mark Dickinson <dickinsm@gmail.com>
parents:
53332
diff
changeset
|
175 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
176 /* Check that what's left begins with a digit or decimal point */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
177 if (!Py_ISDIGIT(*p) && *p != '.') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
178 goto invalid_string; |
|
53468
f76572108dd7
Internal plumbing changes for float parsing:
Mark Dickinson <dickinsm@gmail.com>
parents:
53332
diff
changeset
|
179 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
180 digits_pos = p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
181 if (decimal_point[0] != '.' || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
182 decimal_point[1] != 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
183 { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
184 /* Look for a '.' in the input; if present, it'll need to be |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
185 swapped for the current locale's decimal point before we |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
186 call strtod. On the other hand, if we find the current |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
187 locale's decimal point then the input is invalid. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
188 while (Py_ISDIGIT(*p)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
191 if (*p == '.') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
192 { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
195 /* locate end of number */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
196 while (Py_ISDIGIT(*p)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
199 if (*p == 'e' || *p == 'E') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
200 p++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
201 if (*p == '+' || *p == '-') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
202 p++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
203 while (Py_ISDIGIT(*p)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
204 p++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
205 end = p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
206 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
207 else if (strncmp(p, decimal_point, decimal_point_len) == 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
208 /* Python bug #1417699 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
209 goto invalid_string; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
210 /* For the other cases, we need not convert the decimal |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
211 point */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
212 } |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
213 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
214 if (decimal_point_pos) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
215 char *copy, *c; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
216 /* Create a copy of the input, with the '.' converted to the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
217 locale-specific decimal point */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
218 copy = (char *)PyMem_MALLOC(end - digits_pos + |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
219 1 + decimal_point_len); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
220 if (copy == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
221 *endptr = (char *)nptr; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
222 errno = ENOMEM; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
223 return val; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
224 } |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
225 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
226 c = copy; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
227 memcpy(c, digits_pos, decimal_point_pos - digits_pos); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
228 c += decimal_point_pos - digits_pos; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
229 memcpy(c, decimal_point, decimal_point_len); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
230 c += decimal_point_len; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
231 memcpy(c, decimal_point_pos + 1, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
232 end - (decimal_point_pos + 1)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
233 c += end - (decimal_point_pos + 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
238 if (fail_pos) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
239 { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
240 if (fail_pos > decimal_point_pos) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
241 fail_pos = (char *)digits_pos + |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
242 (fail_pos - copy) - |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
243 (decimal_point_len - 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
244 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
245 fail_pos = (char *)digits_pos + |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
246 (fail_pos - copy); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
247 } |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
248 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
251 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
252 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
253 val = strtod(digits_pos, &fail_pos); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
254 } |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
255 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
256 if (fail_pos == digits_pos) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
259 if (negate && fail_pos != nptr) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
260 val = -val; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
266 *endptr = (char*)nptr; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
267 errno = EINVAL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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, |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
299 char **endptr, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
302 double x, result=-1.0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
305 errno = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
306 PyFPE_START_PROTECT("PyOS_string_to_double", return -1.0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
307 x = _PyOS_ascii_strtod(s, &fail_pos); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
310 if (errno == ENOMEM) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
311 PyErr_NoMemory(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
312 fail_pos = (char *)s; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
313 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
314 else if (!endptr && (fail_pos == s || *fail_pos != '\0')) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
315 PyErr_Format(PyExc_ValueError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
316 "could not convert string to float: " |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
317 "%.200s", s); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
318 else if (fail_pos == s) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
319 PyErr_Format(PyExc_ValueError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
320 "could not convert string to float: " |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
321 "%.200s", s); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
322 else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
323 PyErr_Format(overflow_exception, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
324 "value too large to convert to float: " |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
325 "%.200s", s); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
326 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
329 if (endptr != NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
330 *endptr = fail_pos; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
342 struct lconv *locale_data = localeconv(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
345 if (decimal_point[0] != '.' || decimal_point[1] != 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
348 if (*buffer == '+' || *buffer == '-') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
349 buffer++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
350 while (Py_ISDIGIT(*buffer)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
351 buffer++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
352 if (strncmp(buffer, decimal_point, decimal_point_len) == 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
353 *buffer = '.'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
354 buffer++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
355 if (decimal_point_len > 1) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
356 /* buffer needs to get smaller */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
357 size_t rest_len = strlen(buffer + |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
358 (decimal_point_len - 1)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
359 memmove(buffer, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
360 buffer + (decimal_point_len - 1), |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
361 rest_len); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
362 buffer[rest_len] = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
363 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
364 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
380 char *p = strpbrk(buffer, "eE"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
381 if (p && (*(p + 1) == '-' || *(p + 1) == '+')) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
382 char *start = p + 2; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
383 int exponent_digit_cnt = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
384 int leading_zero_cnt = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
385 int in_leading_zeros = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
388 /* Skip over the exponent and the sign. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
389 p += 2; |
|
46601
7b4081bec783
Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents:
45852
diff
changeset
|
390 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
391 /* Find the end of the exponent, keeping track of leading |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
392 zeros. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
393 while (*p && Py_ISDIGIT(*p)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
394 if (in_leading_zeros && *p == '0') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
395 ++leading_zero_cnt; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
396 if (*p != '0') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
397 in_leading_zeros = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
398 ++p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
399 ++exponent_digit_cnt; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
400 } |
|
46601
7b4081bec783
Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents:
45852
diff
changeset
|
401 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
402 significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
403 if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
404 /* If there are 2 exactly digits, we're done, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
405 regardless of what they contain */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
406 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
407 else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
410 /* There are more than 2 digits in the exponent. See |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
411 if we can delete some of the leading zeros */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
412 if (significant_digit_cnt < MIN_EXPONENT_DIGITS) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
413 significant_digit_cnt = MIN_EXPONENT_DIGITS; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
414 extra_zeros_cnt = exponent_digit_cnt - |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
415 significant_digit_cnt; |
|
46601
7b4081bec783
Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents:
45852
diff
changeset
|
416 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
417 /* Delete extra_zeros_cnt worth of characters from the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
418 front of the exponent */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
421 /* Add one to significant_digit_cnt to copy the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
422 trailing 0 byte, thus setting the length */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
423 memmove(start, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
424 start + extra_zeros_cnt, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
425 significant_digit_cnt + 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
426 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
427 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
428 /* If there are fewer than 2 digits, add zeros |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
429 until there are 2, if there's enough room */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
430 int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
431 if (start + zeros + exponent_digit_cnt + 1 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
432 < buffer + buf_size) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
433 memmove(start + zeros, start, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
434 exponent_digit_cnt + 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
435 memset(start, '0', zeros); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
436 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
437 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
450 p = buffer; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
451 if (*p == '-' || *p == '+') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
452 /* Skip leading sign, if present */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
453 ++p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
454 while (Py_ISDIGIT(*p)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
457 /* if there's no decimal point there's nothing to do */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
458 if (*p++ != '.') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
461 /* scan any digits after the point */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
462 while (Py_ISDIGIT(*p)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
463 ++p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
466 /* scan up to ending '\0' */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
467 while (*p != '\0') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
468 p++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
469 /* +1 to make sure that we move the null byte as well */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
472 /* scan back from fraction_end, looking for removable zeros */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
473 p = old_fraction_end; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
474 while (*(p-1) == '0') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
475 --p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
476 /* and remove point if we've got that far */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
477 if (*(p-1) == '.') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
478 --p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
494 int digit_count, insert_count = 0, convert_to_exp = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
497 /* search for the first non-digit character */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
498 char *p = buffer; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
499 if (*p == '-' || *p == '+') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
500 /* Skip leading sign, if present. I think this could only |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
501 ever be '-', but it can't hurt to check for both. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
502 ++p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
503 digits_start = p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
504 while (*p && Py_ISDIGIT(*p)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
505 ++p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
508 if (*p == '.') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
509 if (Py_ISDIGIT(*(p+1))) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
510 /* Nothing to do, we already have a decimal |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
511 point and a digit after it */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
512 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
513 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
514 /* We have a decimal point, but no following |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
515 digit. Insert a zero after the decimal. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
516 /* can't ever get here via PyOS_double_to_string */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
517 assert(precision == -1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
518 ++p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
519 chars_to_insert = "0"; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
520 insert_count = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
521 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
522 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
523 else if (!(*p == 'e' || *p == 'E')) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
524 /* Don't add ".0" if we have an exponent. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
525 if (digit_count == precision) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
526 /* issue 5864: don't add a trailing .0 in the case |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
527 where the '%g'-formatted result already has as many |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
528 significant digits as were requested. Switch to |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
529 exponential notation instead. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
530 convert_to_exp = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
531 /* no exponent, no point, and we shouldn't land here |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
532 for infs and nans, so we must be at the end of the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
533 string. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
534 assert(*p == '\0'); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
535 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
536 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
537 assert(precision == -1 || digit_count < precision); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
538 chars_to_insert = ".0"; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
539 insert_count = 2; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
540 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
541 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
542 if (insert_count) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
543 size_t buf_len = strlen(buffer); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
544 if (buf_len + insert_count + 1 >= buf_size) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
545 /* If there is not enough room in the buffer |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
546 for the additional text, just skip it. It's |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
547 not worth generating an error over. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
548 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
549 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
550 memmove(p + insert_count, p, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
551 buffer + strlen(buffer) - p + 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
552 memcpy(p, chars_to_insert, insert_count); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
553 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
554 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
555 if (convert_to_exp) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
556 int written; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
557 size_t buf_avail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
558 p = digits_start; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
559 /* insert decimal point */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
560 assert(digit_count >= 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
561 memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
562 p[1] = '.'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
563 p += digit_count+1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
564 assert(p <= buf_size+buffer); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
565 buf_avail = buf_size+buffer-p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
566 if (buf_avail == 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
567 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
568 /* Add exponent. It's okay to use lower case 'e': we only |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
569 arrive here as a result of using the empty format code or |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
570 repr/str builtins and those never want an upper case 'E' */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
571 written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
572 if (!(0 <= written && |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
573 written < Py_SAFE_DOWNCAST(buf_avail, size_t, int))) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
574 /* output truncated, or something else bad happened */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
575 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
576 remove_trailing_zeros(buffer); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
577 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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'. |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 * |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
605 _PyOS_ascii_formatd(char *buffer, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
606 size_t buf_size, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
607 const char *format, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
608 double d, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
611 char format_char; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
614 /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
615 also with at least one character past the decimal. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
618 /* The last character in the format string must be the format char */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
621 if (format[0] != '%') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
624 /* I'm not sure why this test is here. It's ensuring that the format |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
625 string after the first character doesn't have a single quote, a |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
626 lowercase l, or a percent. This is the reverse of the commented-out |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
627 test about 10 lines ago. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
628 if (strpbrk(format + 1, "'l%")) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
631 /* Also curious about this function is that it accepts format strings |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
632 like "%xg", which are invalid for floats. In general, the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
633 interface to this function is not very good, but changing it is |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
636 if (!(format_char == 'e' || format_char == 'E' || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
637 format_char == 'f' || format_char == 'F' || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
638 format_char == 'g' || format_char == 'G' || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
639 format_char == 'Z')) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
642 /* Map 'Z' format_char to 'g', by copying the format string and |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
643 replacing the final char with a 'g' */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
644 if (format_char == 'Z') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
645 if (format_len + 1 >= sizeof(tmp_format)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
646 /* The format won't fit in our copy. Error out. In |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
647 practice, this will never happen and will be |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
648 detected by returning NULL */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
649 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
650 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
651 strcpy(tmp_format, format); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
652 tmp_format[format_len - 1] = 'g'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
653 format = tmp_format; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
657 /* Have PyOS_snprintf do the hard work */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
662 /* Get the current locale, and find the decimal point string. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
663 Convert that string back to a dot. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
666 /* If an exponent exists, ensure that the exponent is at least |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
667 MIN_EXPONENT_DIGITS digits, providing the buffer is large enough |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
668 for the extra zeros. Also, if there are more than |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
669 MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
670 back to MIN_EXPONENT_DIGITS */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
673 /* If format_char is 'Z', make sure we have at least one character |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
674 after the decimal point (and make sure we have a decimal point); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
675 also switch to exponential notation in some edge cases where the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
676 extra character would produce more significant digits that we |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
677 really want. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
678 if (format_char == 'Z') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
692 char format[32]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
693 Py_ssize_t bufsize; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
694 char *buf; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
695 int t, exp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
698 /* Validate format_code, and map upper and lower case */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
699 switch (format_code) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
700 case 'e': /* exponent */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
701 case 'f': /* fixed */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
702 case 'g': /* general */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
703 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
704 case 'E': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
705 upper = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
706 format_code = 'e'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
707 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
708 case 'F': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
709 upper = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
710 format_code = 'f'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
711 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
712 case 'G': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
713 upper = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
714 format_code = 'g'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
715 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
716 case 'r': /* repr format */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
717 /* Supplied precision is unused, must be 0. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
718 if (precision != 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
719 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
720 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
721 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
722 /* The repr() precision (17 significant decimal digits) is the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
723 minimal number that is guaranteed to have enough precision |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
724 so that if the number is read back in the exact same binary |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
725 value is recreated. This is true for IEEE floating point |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
726 by design, and also happens to work for all other modern |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
727 hardware. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
728 precision = 17; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
729 format_code = 'g'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
730 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
731 default: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
732 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
733 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
736 /* Here's a quick-and-dirty calculation to figure out how big a buffer |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
741 1 for a possible sign |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
742 1 for a possible decimal point |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
743 2 for a possible [eE][+-] |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
744 1 for each digit of the exponent; if we allow 19 digits |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
745 total then we're safe up to exponents of 2**63. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
748 This gives a total of 24 + the number of digits in the significand, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
751 for 'g' format: at most precision, except possibly |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
752 when precision == 0, when it's 1. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
753 for 'e' format: precision+1 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
754 for 'f' format: precision digits after the point, at least 1 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
755 before. To figure out how many digits appear before the point |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
756 we have to examine the size of the number. If fabs(val) < 1.0 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
757 then there will be only one digit before the point. If |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
762 digits before the point (where the 'ceiling' allows for the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
763 possibility that the rounding rounds the integer part of val |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
764 up). A safe upper bound for the above quantity is |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
765 1+floor(exp/3), where exp is the unique integer such that 0.5 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
766 <= fabs(val)/2**exp < 1.0. This exp can be obtained from |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
769 So we allow room for precision+1 digits for all formats, plus an |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
774 if (Py_IS_NAN(val) || Py_IS_INFINITY(val)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
775 /* 3 for 'inf'/'nan', 1 for sign, 1 for '\0' */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
776 bufsize = 5; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
777 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
778 bufsize = 25 + precision; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
779 if (format_code == 'f' && fabs(val) >= 1.0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
780 frexp(val, &exp); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
781 bufsize += exp/3; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
782 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
785 buf = PyMem_Malloc(bufsize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
786 if (buf == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
787 PyErr_NoMemory(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
788 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
791 /* Handle nan and inf. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
792 if (Py_IS_NAN(val)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
793 strcpy(buf, "nan"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
794 t = Py_DTST_NAN; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
795 } else if (Py_IS_INFINITY(val)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
796 if (copysign(1., val) == 1.) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
797 strcpy(buf, "inf"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
798 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
799 strcpy(buf, "-inf"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
800 t = Py_DTST_INFINITE; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
801 } else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
802 t = Py_DTST_FINITE; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
803 if (flags & Py_DTSF_ADD_DOT_0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
806 PyOS_snprintf(format, sizeof(format), "%%%s.%i%c", |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
807 (flags & Py_DTSF_ALT ? "#" : ""), precision, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
808 format_code); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
809 _PyOS_ascii_formatd(buf, bufsize, format, val, precision); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
812 /* Add sign when requested. It's convenient (esp. when formatting |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
813 complex numbers) to include a sign even for inf and nan. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
814 if (flags & Py_DTSF_SIGN && buf[0] != '-') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
815 size_t len = strlen(buf); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
816 /* the bufsize calculations above should ensure that we've got |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
817 space to add a sign */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
818 assert((size_t)bufsize >= len+2); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
819 memmove(buf+1, buf, len+1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
820 buf[0] = '+'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
821 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
822 if (upper) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
823 /* Convert to upper case. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
824 char *p1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
825 for (p1 = buf; *p1; p1++) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
826 *p1 = Py_TOUPPER(*p1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
829 if (type) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
830 *type = t; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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[] = { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
846 "inf", |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
847 "nan", |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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[] = { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
851 "INF", |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
852 "NAN", |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
877 Py_DTST_FINITE |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
878 Py_DTST_INFINITE |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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, |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
887 int mode, Py_ssize_t precision, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
888 int always_add_sign, int add_dot_0_if_integer, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
891 char *buf = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
892 char *p = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
893 Py_ssize_t bufsize = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
894 char *digits, *digits_end; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
895 int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
896 Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
899 /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
900 Must be matched by a call to _Py_dg_freedtoa. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
901 _Py_SET_53BIT_PRECISION_START; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
902 digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
903 &digits_end); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
906 decpt = (Py_ssize_t)decpt_as_int; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
907 if (digits == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
908 /* The only failure mode is no memory. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
909 PyErr_NoMemory(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
910 goto exit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
911 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
912 assert(digits_end != NULL && digits_end >= digits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
915 if (digits_len && !Py_ISDIGIT(digits[0])) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
916 /* Infinities and nans here; adapt Gay's output, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
917 so convert Infinity to inf and NaN to nan, and |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
920 /* ignore the actual sign of a nan */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
921 if (digits[0] == 'n' || digits[0] == 'N') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
924 /* We only need 5 bytes to hold the result "+inf\0" . */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
925 bufsize = 5; /* Used later in an assert. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
926 buf = (char *)PyMem_Malloc(bufsize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
927 if (buf == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
928 PyErr_NoMemory(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
929 goto exit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
930 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
933 if (sign == 1) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
934 *p++ = '-'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
935 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
936 else if (always_add_sign) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
937 *p++ = '+'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
938 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
939 if (digits[0] == 'i' || digits[0] == 'I') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
940 strncpy(p, float_strings[OFS_INF], 3); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
943 if (type) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
944 *type = Py_DTST_INFINITE; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
945 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
946 else if (digits[0] == 'n' || digits[0] == 'N') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
947 strncpy(p, float_strings[OFS_NAN], 3); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
950 if (type) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
951 *type = Py_DTST_NAN; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
952 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
953 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
954 /* shouldn't get here: Gay's code should always return |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
955 something starting with a digit, an 'I', or 'N' */ |
|
62910
5025ba0553b6
Revert temporary debugging commits (r82752, r82754).
Mark Dickinson <dickinsm@gmail.com>
parents:
62909
diff
changeset
|
956 strncpy(p, "ERR", 3); |
|
68102
e2f96bd29252
Issue #8914: fix various warnings from the Clang static analyzer v254.
Brett Cannon <bcannon@gmail.com>
parents:
61466
diff
changeset
|
957 /* p += 3; */ |
|
62910
5025ba0553b6
Revert temporary debugging commits (r82752, r82754).
Mark Dickinson <dickinsm@gmail.com>
parents:
62909
diff
changeset
|
958 assert(0); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
959 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
960 goto exit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
963 /* The result must be finite (not inf or nan). */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
964 if (type) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
968 /* We got digits back, format them. We may need to pad 'digits' |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
969 either on the left or right (or both) with extra zeros, so in |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
974 where either of the <zeros> pieces could be empty, and there's a |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
975 decimal point that could appear either in <digits> or in the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
978 Imagine an infinite 'virtual' string vdigits, consisting of the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
979 string 'digits' (starting at index 0) padded on both the left and |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
984 of this virtual string. Thus if vdigits_start < 0 then we'll end |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
985 up producing some leading zeros; if vdigits_end > digits_len there |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
986 will be trailing zeros in the output. The next section of code |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
987 determines whether to use an exponent or not, figures out the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
988 position 'decpt' of the decimal point, and computes 'vdigits_start' |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
989 and 'vdigits_end'. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
990 vdigits_end = digits_len; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
991 switch (format_code) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
992 case 'e': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
993 use_exp = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
994 vdigits_end = precision; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
995 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
996 case 'f': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
997 vdigits_end = decpt + precision; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
998 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
999 case 'g': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1000 if (decpt <= -4 || decpt > |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1001 (add_dot_0_if_integer ? precision-1 : precision)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1002 use_exp = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1003 if (use_alt_formatting) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1004 vdigits_end = precision; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1005 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1006 case 'r': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1007 /* convert to exponential format at 1e16. We used to convert |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1008 at 1e17, but that gives odd-looking results for some values |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1009 when a 16-digit 'shortest' repr is padded with bogus zeros. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1010 For example, repr(2e16+8) would give 20000000000000010.0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1011 the true value is 20000000000000008.0. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1012 if (decpt <= -4 || decpt > 16) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1013 use_exp = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1014 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1015 default: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1016 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1017 goto exit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1020 /* if using an exponent, reset decimal point position to 1 and adjust |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1021 exponent accordingly.*/ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1022 if (use_exp) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1023 exp = decpt - 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1024 decpt = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1025 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1026 /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start < |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1027 decpt < vdigits_end if add_dot_0_if_integer and no exponent */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1028 vdigits_start = decpt <= 0 ? decpt-1 : 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1029 if (!use_exp && add_dot_0_if_integer) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1030 vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1031 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1034 /* double check inequalities */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1035 assert(vdigits_start <= 0 && |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1036 0 <= digits_len && |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1037 digits_len <= vdigits_end); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1038 /* decimal point should be in (vdigits_start, vdigits_end] */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1041 /* Compute an upper bound how much memory we need. This might be a few |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1042 chars too long, but no big deal. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1043 bufsize = |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1044 /* sign, decimal point and trailing 0 byte */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1047 /* total digit count (including zero padding on both sides) */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1050 /* exponent "e+100", max 3 numerical digits */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1053 /* Now allocate the memory and initialize p to point to the start of |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1054 it. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1055 buf = (char *)PyMem_Malloc(bufsize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1056 if (buf == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1057 PyErr_NoMemory(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1058 goto exit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1059 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1062 /* Add a negative sign if negative, and a plus sign if non-negative |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1063 and always_add_sign is true. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1064 if (sign == 1) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1065 *p++ = '-'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1066 else if (always_add_sign) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1069 /* note that exactly one of the three 'if' conditions is true, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1070 so we include exactly one decimal point */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1071 /* Zero padding on left of digit string */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1072 if (decpt <= 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1073 memset(p, '0', decpt-vdigits_start); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1074 p += decpt - vdigits_start; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1075 *p++ = '.'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1076 memset(p, '0', 0-decpt); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1077 p += 0-decpt; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1078 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1079 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1080 memset(p, '0', 0-vdigits_start); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1081 p += 0 - vdigits_start; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1084 /* Digits, with included decimal point */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1085 if (0 < decpt && decpt <= digits_len) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1086 strncpy(p, digits, decpt-0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1087 p += decpt-0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1088 *p++ = '.'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1089 strncpy(p, digits+decpt, digits_len-decpt); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1090 p += digits_len-decpt; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1091 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1092 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1093 strncpy(p, digits, digits_len); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1094 p += digits_len; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1097 /* And zeros on the right */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1098 if (digits_len < decpt) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1099 memset(p, '0', decpt-digits_len); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1100 p += decpt-digits_len; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1101 *p++ = '.'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1102 memset(p, '0', vdigits_end-decpt); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1103 p += vdigits_end-decpt; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1104 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1105 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1106 memset(p, '0', vdigits_end-digits_len); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1107 p += vdigits_end-digits_len; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1110 /* Delete a trailing decimal pt unless using alternative formatting. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1111 if (p[-1] == '.' && !use_alt_formatting) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1114 /* Now that we've done zero padding, add an exponent if needed. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1115 if (use_exp) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1116 *p++ = float_strings[OFS_E][0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1117 exp_len = sprintf(p, "%+.02d", exp); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1118 p += exp_len; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1121 if (buf) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1122 *p = '\0'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1123 /* It's too late if this fails, as we've already stepped on |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1124 memory that isn't ours. But it's an okay debugging test. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1125 assert(p-buf < bufsize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1126 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1127 if (digits) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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, |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1135 char format_code, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1136 int precision, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1137 int flags, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1140 char **float_strings = lc_float_strings; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1143 /* Validate format_code, and map upper and lower case. Compute the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1144 mode and make any adjustments as needed. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1145 switch (format_code) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1146 /* exponent */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1147 case 'E': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1148 float_strings = uc_float_strings; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1149 format_code = 'e'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1150 /* Fall through. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1151 case 'e': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1152 mode = 2; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1153 precision++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1154 break; |
|
53190
d84ad973cde2
Simplify PyOS_double_to_string.
Eric Smith <eric@trueblade.com>
parents:
53187
diff
changeset
|
1155 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1156 /* fixed */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1157 case 'F': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1158 float_strings = uc_float_strings; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1159 format_code = 'f'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1160 /* Fall through. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1161 case 'f': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1162 mode = 3; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1163 break; |
|
53190
d84ad973cde2
Simplify PyOS_double_to_string.
Eric Smith <eric@trueblade.com>
parents:
53187
diff
changeset
|
1164 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1165 /* general */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1166 case 'G': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1167 float_strings = uc_float_strings; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1168 format_code = 'g'; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1169 /* Fall through. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1170 case 'g': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1171 mode = 2; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1172 /* precision 0 makes no sense for 'g' format; interpret as 1 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1173 if (precision == 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1174 precision = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1175 break; |
|
53190
d84ad973cde2
Simplify PyOS_double_to_string.
Eric Smith <eric@trueblade.com>
parents:
53187
diff
changeset
|
1176 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1177 /* repr format */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1178 case 'r': |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1179 mode = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1180 /* Supplied precision is unused, must be 0. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1181 if (precision != 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1182 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1183 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1184 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1185 break; |
|
53190
d84ad973cde2
Simplify PyOS_double_to_string.
Eric Smith <eric@trueblade.com>
parents:
53187
diff
changeset
|
1186 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1187 default: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1188 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1189 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1192 return format_float_short(val, format_code, mode, precision, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1193 flags & Py_DTSF_SIGN, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1194 flags & Py_DTSF_ADD_DOT_0, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
diff
changeset
|
1195 flags & Py_DTSF_ALT, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
58468
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 */ |
