classification
Title: Wrong default precision in documentation for format
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.4, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Barium, docs@python, eric.smith, mark.dickinson, python-dev, terry.reedy
Priority: normal Keywords: patch

Created on 2014-10-03 09:31 by Barium, last changed 2014-10-06 06:06 by terry.reedy. This issue is now closed.

Files
File name Uploaded Description Edit
missing_type_specifier.patch mark.dickinson, 2014-10-04 08:18 review
missing_type_specifier2.patch mark.dickinson, 2014-10-04 08:25 review
Messages (10)
msg228318 - (view) Author: Tommy Andersen (Barium) Date: 2014-10-03 09:31
The format documentation for the Format Specification Mini-Language for python 3.3 (perhaps newer and older as well) at: https://docs.python.org/3.3/library/string.html 

States for type '' (for floating point numbers):

    Similar to 'g', except with at least one digit past the decimal point and a default precision of 12. This is intended to match str(), except you can add the other format modifiers.

This appears not to be true, the following code example, run in Python 3.3.2:

>>> '{}'.format(3.14159265358979323846264338327950288419)
'3.141592653589793'

As it can be seen form the output the default precision appears to be 15.
msg228323 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2014-10-03 11:06
I think this is a result of changing the precision of str() to match repr().

2.7 prints:
'3.14159265359'
msg228367 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-10-03 20:23
"The precision is a decimal number indicating how many digits should be displayed ... before and after the decimal point for a floating point value formatted with 'g' or 'G'. It seems that str, repr, and '' are using precision 16, and the doc should be changed to match.

>>>str(.314159265358979323846264338327950288419)
'0.3141592653589793' # 16, not counting 0.

>>> '{}'.format(3.14159265358979323846264338327950288419)
'3.141592653589793'
>>> '{:.16g}'.format(3.14159265358979323846264338327950288419)
'3.141592653589793'
>>> str(3.14159265358979323846264338327950288419)
'3.141592653589793'  # 16

But I discovered this 'anomaly' (bug?)
>>> str(31.4159265358979323846264338327950288419)
'31.41592653589793'
>>> str(33.14159265358979323846264338327950288419)
'33.1415926535898'  # precision 15
I expected this last to be
'33.14159265358979'
as 32... rounds down, not up.

repr and '{}'.format act the same.
msg228435 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-04 07:55
> It seems that str, repr, and '' are using precision 16

None of them is using a fixed precision: they're all using David Gay's implementation of the "shortest string" algorithm (à la Burger and Dybvig).   For repr, this is the case since Python 3.1 / 2.7; for str and formatting with no type specifier, since Python 3.2.  The docs definitely do need updating here.

> I expected this last to be
> '33.14159265358979'

'33.1415926535898' is shorter, and rounds back to the same floating-point number, so that's what Gay's algorithm gives here.
msg228438 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-04 08:18
Here's a proposed fix.
msg228439 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-04 08:25
Hmm;  it's only outputs in non-scientific notation that are guaranteed to have a decimal point.  Patch updated.
msg228512 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-10-04 23:53
I see now that my expectation, based on decimal rounding rather than binary conversion and rounding, was wrong ;-)
>>> 33.14159265358979323846264338327950288419 == 33.1415926535898
True
>>> 33.14159265358979323846264338327950288419 == 33.14159265358979
False
>>> format(33.14159265358979323846264338327950288419, '.18')
'33.1415926535897967'

Tommy: 3.3 only gets security fixes.  When a core developer (indicated by the blue and yellow snake symbol) resets Versions, you should leave them alone or ask before changing.

As for the patch: 'non-scientific' == 'fixed-point', the expression already used in the table. The rewrite omits the fact the exception is to match str and that g and str are otherwise the same except for fixed versus 'as needed' precision.  I note that '' = 'd' for integers also makes '' for integers similar to str() as modified by the preceding options.  An alternate rewrite:

Similar to 'g', except that fixed-point notation, when used, has at least one digit past the decimal point.  The default precision is as high as needed to represent the particular value. The overall effect is to match the output of str() as altered by the other format modifiers.

--
The following in the examples could be fixed in the same patch
>>> '{:+f}; {:+f}'.format(3.14, -3.14)  # show it always
'+3.140000; -3.140000'

add to the comment 'it always displays a sign'.
msg228542 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-05 08:23
Terry: your rewrite looks fine to me.  +1 for committing that.
msg228643 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2014-10-06 06:05
New changeset 041d0752171a by Terry Jan Reedy in branch '3.4':
Issue #22546: update doc for mini-language float None presentation type.
https://hg.python.org/cpython/rev/041d0752171a
msg228644 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-10-06 06:06
Tommy, thanks for reporting this.
History
Date User Action Args
2014-10-06 06:06:23terry.reedysetstatus: open -> closed
resolution: fixed
messages: + msg228644

stage: needs patch -> resolved
2014-10-06 06:05:09python-devsetnosy: + python-dev
messages: + msg228643
2014-10-05 08:23:35mark.dickinsonsetmessages: + msg228542
2014-10-04 23:53:46terry.reedysetmessages: + msg228512
versions: - Python 3.3
2014-10-04 08:25:12mark.dickinsonsetfiles: + missing_type_specifier2.patch

messages: + msg228439
2014-10-04 08:18:31mark.dickinsonsetfiles: + missing_type_specifier.patch
keywords: + patch
messages: + msg228438
2014-10-04 08:03:39Bariumsetversions: + Python 3.3
2014-10-04 07:55:56mark.dickinsonsetmessages: + msg228435
2014-10-03 20:23:18terry.reedysetversions: + Python 3.4, Python 3.5, - Python 3.3
nosy: + terry.reedy

messages: + msg228367

type: behavior
stage: needs patch
2014-10-03 11:06:13eric.smithsetmessages: + msg228323
2014-10-03 11:03:04eric.smithsetnosy: + mark.dickinson, eric.smith
2014-10-03 09:31:18Bariumcreate