[Python-checkins] r71517 - in python/branches/py3k-short-float-repr: Lib/test/test_types.py Objects/stringlib/formatter.h
eric.smith
python-checkins at python.org
Sun Apr 12 17:10:08 CEST 2009
Author: eric.smith
Date: Sun Apr 12 17:10:08 2009
New Revision: 71517
Log:
Significant cleanup, simplification, and correction of padding code. Added tests that previously failed.
Modified:
python/branches/py3k-short-float-repr/Lib/test/test_types.py
python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h
Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py
==============================================================================
--- python/branches/py3k-short-float-repr/Lib/test/test_types.py (original)
+++ python/branches/py3k-short-float-repr/Lib/test/test_types.py Sun Apr 12 17:10:08 2009
@@ -557,6 +557,29 @@
test(1.1e200, '+g', '+1.1e+200')
test(1.1e200, '+', '+1.1e+200')
+ # 0 padding
+ test(1234., '010f', '1234.000000')
+ test(1234., '011f', '1234.000000')
+ test(1234., '012f', '01234.000000')
+ test(-1234., '011f', '-1234.000000')
+ test(-1234., '012f', '-1234.000000')
+ test(-1234., '013f', '-01234.000000')
+ test(-1234.12341234, '013f', '-01234.123412')
+ test(-123456.12341234, '011.2f', '-0123456.12')
+
+ # 0 padding with commas
+ test(1234., '011,f', '1,234.000000')
+ test(1234., '012,f', '1,234.000000')
+ test(1234., '013,f', '01,234.000000')
+ test(-1234., '012,f', '-1,234.000000')
+ test(-1234., '013,f', '-1,234.000000')
+ test(-1234., '014,f', '-01,234.000000')
+ test(-12345., '015,f', '-012,345.000000')
+ test(-123456., '016,f', '-0,123,456.000000')
+ test(-123456., '017,f', '-0,123,456.000000')
+ test(-123456.12341234, '017,f', '-0,123,456.123412')
+ test(-123456.12341234, '013,.2f', '-0,123,456.12')
+
# % formatting
test(-1.0, '%', '-100.000000%')
Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h
==============================================================================
--- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original)
+++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Sun Apr 12 17:10:08 2009
@@ -277,9 +277,10 @@
Py_ssize_t n_decimal; /* 0 if only an integer */
Py_ssize_t n_remainder; /* digits in decimal and/or exponent part,
excluding the decimal itself, if present */
- Py_ssize_t n_total; /* just a convenience, it's derivable from the
- other fields */
+ /* These 2 are calculatable from parameters, but needed between
+ calls to calc_number_widths and fill_number in order to not
+ have to pass all of the parameters to fill_number. */
Py_ssize_t n_digits; /* The number of digits before a decimal or
exponent. */
Py_ssize_t n_min_width; /* The min_width we used when we computed
@@ -321,7 +322,7 @@
unused. should this take discrete params in order to be more clear
about what it does? or is passing a single format parameter easier
and more efficient enough to justify a little obfuscation? */
-static void
+static Py_ssize_t
calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
STRINGLIB_CHAR sign_char, STRINGLIB_CHAR *number,
Py_ssize_t n_number, Py_ssize_t n_remainder,
@@ -329,6 +330,7 @@
const InternalFormatSpec *format)
{
Py_ssize_t n_non_digit_non_padding;
+ Py_ssize_t n_padding;
spec->n_digits = n_number - n_remainder - (has_decimal?1:0);
spec->n_lpadding = 0;
@@ -377,7 +379,7 @@
}
}
- /* The number of chars used for non-digit and non-padding. */
+ /* The number of chars used for non-digits and non-padding. */
n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal +
spec->n_remainder;
@@ -400,36 +402,32 @@
locale->grouping,
locale->thousands_sep);
- if (format->width == -1) {
- /* no padding at all, nothing to do */
- }
- else {
- /* see if any padding is needed */
- if (spec->n_sign + spec->n_grouped_digits +
- spec->n_prefix >= format->width) {
- /* no padding needed, we're already bigger than the
- requested width */
- }
- else {
- /* determine which of left, space, or right padding is
- needed */
- Py_ssize_t padding = format->width -
- (spec->n_sign + spec->n_grouped_digits + n_prefix);
- if (format->align == '<')
- spec->n_rpadding = padding;
- else if (format->align == '>')
- spec->n_lpadding = padding;
- else if (format->align == '^') {
- spec->n_lpadding = padding / 2;
- spec->n_rpadding = padding - spec->n_lpadding;
- }
- else if (format->align == '=')
- spec->n_spadding = padding;
- else
- spec->n_lpadding = padding;
+ /* Given the desired width and the total of digit and non-digit
+ space we consume, see if we need any padding. format->width can
+ be negative (meaning no padding), but this code still works in
+ that case. */
+ n_padding = format->width -
+ (n_non_digit_non_padding + spec->n_grouped_digits);
+ if (n_padding > 0) {
+ /* Some padding is needed. Determine if it's left, space, or right. */
+ switch (format->align) {
+ case '<':
+ spec->n_rpadding = n_padding;
+ break;
+ case '^':
+ spec->n_lpadding = n_padding / 2;
+ spec->n_rpadding = n_padding - spec->n_lpadding;
+ break;
+ case '=':
+ spec->n_spadding = n_padding;
+ break;
+ default:
+ /* Handles '>', plus catch-all just in case. */
+ spec->n_lpadding = n_padding;
+ break;
}
}
- spec->n_total = spec->n_lpadding + spec->n_sign + spec->n_prefix +
+ return spec->n_lpadding + spec->n_sign + spec->n_prefix +
spec->n_spadding + spec->n_grouped_digits + spec->n_decimal +
spec->n_remainder + spec->n_rpadding;
}
@@ -670,6 +668,7 @@
Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which
produces non-digits */
Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */
+ Py_ssize_t n_total;
STRINGLIB_CHAR *prefix = NULL;
NumberFieldWidths spec;
long x;
@@ -804,11 +803,11 @@
&locale);
/* Calculate how much memory we'll need. */
- calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars,
+ n_total = calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars,
n_digits, n_remainder, 0, &locale, format);
/* Allocate the memory. */
- result = STRINGLIB_NEW(NULL, spec.n_total);
+ result = STRINGLIB_NEW(NULL, n_total);
if (!result)
goto done;
@@ -846,6 +845,7 @@
char *buf = NULL; /* buffer returned from PyOS_double_to_string */
Py_ssize_t n_digits;
Py_ssize_t n_remainder;
+ Py_ssize_t n_total;
int has_decimal;
double val;
Py_ssize_t precision = format->precision;
@@ -950,11 +950,11 @@
&locale);
/* Calculate how much memory we'll need. */
- calc_number_widths(&spec, 0, sign_char, p, n_digits, n_remainder,
- has_decimal, &locale, format);
+ n_total = calc_number_widths(&spec, 0, sign_char, p, n_digits,
+ n_remainder, has_decimal, &locale, format);
/* Allocate the memory. */
- result = STRINGLIB_NEW(NULL, spec.n_total);
+ result = STRINGLIB_NEW(NULL, n_total);
if (result == NULL)
goto done;
More information about the Python-checkins
mailing list