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