From 6cd82a38f184d9d5dfc0e8544f76c9f510771919 Mon Sep 17 00:00:00 2001 From: "mark.dickinson" Date: Mon, 23 Nov 2009 20:54:09 +0000 Subject: [PATCH] Issue #7117, continued: Remove substitution of %g-style formatting for %f-style formatting, which used to occur at high precision. Float formatting should now be consistent between 2.7 and 3.1. git-svn-id: http://svn.python.org/projects/python/trunk@76472 6015fed2-1504-0410-9fe1-9d1591cc4771 --- Doc/library/stdtypes.rst | 10 +++------- Lib/test/test_types.py | 23 +++++++++++++++++++---- Misc/NEWS | 3 +++ Objects/stringlib/formatter.h | 6 ------ Objects/stringobject.c | 3 --- Objects/unicodeobject.c | 3 --- 6 files changed, 25 insertions(+), 23 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 66de1296b2..7ce2a30d7c 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1453,9 +1453,9 @@ that ``'\0'`` is the end of the string. .. XXX Examples? -For safety reasons, floating point precisions are clipped to 50; ``%f`` -conversions for numbers whose absolute value is over 1e50 are replaced by ``%g`` -conversions. [#]_ All other errors raise exceptions. +.. versionchanged:: 2.7 + ``%f`` conversions for numbers whose absolute value is over 1e50 are no + longer replaced by ``%g`` conversions. .. index:: module: string @@ -2875,10 +2875,6 @@ The following attributes are only supported by :term:`new-style class`\ es. .. [#] To format only a tuple you should therefore provide a singleton tuple whose only element is the tuple to be formatted. -.. [#] These numbers are fairly arbitrary. They are intended to avoid printing endless - strings of meaningless digits without hampering correct use and without having - to know the exact precision of floating point values on a particular machine. - .. [#] The advantage of leaving the newline on is that returning an empty string is then an unambiguous EOF indication. It is also possible (in cases where it might matter, for example, if you want to make an exact copy of a file while diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 8e9dd72066..18ab9cc84b 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -601,10 +601,25 @@ class TypesTests(unittest.TestCase): test(-1.0, ' f', '-1.000000') test( 1.0, '+f', '+1.000000') test(-1.0, '+f', '-1.000000') - test(1.1234e90, 'f', '1.1234e+90') - test(1.1234e90, 'F', '1.1234e+90') - test(1.1234e200, 'f', '1.1234e+200') - test(1.1234e200, 'F', '1.1234e+200') + + # Python versions <= 2.6 switched from 'f' to 'g' formatting for + # values larger than 1e50. No longer. + f = 1.1234e90 + for fmt in 'f', 'F': + # don't do a direct equality check, since on some + # platforms only the first few digits of dtoa + # will be reliable + result = f.__format__(fmt) + self.assertEqual(len(result), 98) + self.assertEqual(result[-7], '.') + self.assertTrue(result[:12] in ('112340000000', '112339999999')) + f = 1.1234e200 + for fmt in 'f', 'F': + result = f.__format__(fmt) + self.assertEqual(len(result), 208) + self.assertEqual(result[-7], '.') + self.assertTrue(result[:12] in ('112340000000', '112339999999')) + test( 1.0, 'e', '1.000000e+00') test(-1.0, 'e', '-1.000000e+00') diff --git a/Misc/NEWS b/Misc/NEWS index 58b7057164..d582e39fdb 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 1 Core and Builtins ----------------- +- Remove switch from "%f" formatting to "%g" formatting for floats + larger than 1e50 in absolute value. + - Remove restrictions on precision when formatting floats. E.g., "%.120g" % 1e-100 used to raise OverflowError, but now gives the requested 120 significant digits instead. diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index c722460472..f09578fa13 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -957,12 +957,6 @@ format_float_internal(PyObject *value, if (precision < 0) precision = default_precision; -#if PY_VERSION_HEX < 0x03010000 - /* 3.1 no longer converts large 'f' to 'g'. */ - if ((type == 'f' || type == 'F') && fabs(val) >= 1e50) - type = 'g'; -#endif - /* Cast "type", because if we're in unicode we need to pass a 8-bit char. This is safe, because we've restricted what "type" can be. */ diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 1d9ba8cd5b..6636b9af6d 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -4398,9 +4398,6 @@ formatfloat(PyObject *v, int flags, int prec, int type) if (prec < 0) prec = 6; - if (type == 'f' && fabs(x) >= 1e50) - type = 'g'; - p = PyOS_double_to_string(x, type, prec, (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 401f7bea2d..2fa004eae1 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8318,9 +8318,6 @@ formatfloat(PyObject *v, int flags, int prec, int type) if (prec < 0) prec = 6; - if (type == 'f' && fabs(x) >= 1e50) - type = 'g'; - p = PyOS_double_to_string(x, type, prec, (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); if (p == NULL) -- 2.11.4.GIT