Issue42429

Created on **2020-11-21 23:29** by **Kwpolska**, last changed **2020-11-23 18:31** by **mark.dickinson**.

Messages (6) | |||
---|---|---|---|

msg381578 - (view) | Author: Chris Warrick (Kwpolska) | Date: 2020-11-21 23:29 | |

When formatting decimal.Decimal using old-style formatting (%g), the output is as short as possible, as expected. When using new-style formatting (str.format or f-strings), the output uses the input precision. Floats behave correctly with new-style formatting. Python 3.9.0 (default, Oct 27 2020, 14:15:17) [Clang 12.0.0 (clang-1200.0.32.21)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import decimal >>> d1 = decimal.Decimal("1.000") >>> d2 = decimal.Decimal("1.500") >>> f1 = 1.0 >>> f2 = 1.5 >>> f"{d1:g} {f1:g}" '1.000 1' >>> f"{d2:g} {f2:g}" '1.500 1.5' >>> "%g %g" % (d1, f1) '1 1' >>> "%g %g" % (d2, f2) '1.5 1.5' |
|||

msg381587 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2020-11-22 03:28 | |

A few things: - There is no %-formatting for Decimal types. They're being converted to float first. That's why it appears that %-formatting with 'g' works the same for decimal and float: you're really just calling the float version. - The difference in 'g' formatting between float and Decimal is a known difference. This issue pops up every now and again, but right now I can't find where (or if) it's actually documented. Mark: can you point to it? I don't think https://docs.python.org/3/library/string.html#format-specification-mini-language mentions it where it talks about Decimals. And I don't see any documentation for Decimal.__format__. |
|||

msg381666 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2020-11-23 12:56 | |

Hmm. I'm not sure that it ever got documented properly. There may still be an open documentation issue somewhere. There's not really much wiggle-room for changing the implementation: the behaviour of the "g" formatting for Decimal objects is following the specification of "to-scientific-string" from the Decimal Arithmetic spec that the decimal module is based on: http://speleotrove.com/decimal/daconvs.html#reftostr One of the principles articulated there is that to-scientific-string should be faithful, so that conversion to string and back doesn't lose any information. That precludes chopping significant trailing zeros. |
|||

msg381682 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2020-11-23 17:24 | |

Some references after a bit of tracker digging: - #7098 is the original issue where the behaviour was considered. - #23460 is related, and _did_ result in a documentation change, but that documentation change didn't say anything about preserving trailing zeros - #13433 is relevant, and still open So I think we're still missing a documentation update. |
|||

msg381684 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2020-11-23 17:55 | |

There's also #39096. |
|||

msg381686 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2020-11-23 18:31 | |

Here's a first draft of proposed re-wording for the 'e', 'f' and 'g' sections of the table in the general format-specification mini-language docs. (I started making a PR, but got too annoyed with the mechanics of editing reStructuredText tables.) 'e': Scientific "E" notation. For a given precision ``p >= 0``, formats the number in scientific notation with the letter 'e' separating the coefficient from the exponent. The coefficient has one digit before and ``p`` digits after the decimal point, for a total of ``p + 1`` significant digits. With no precision, uses a precision of ``6`` digits after the decimal point for :class:`float`, and shows all coefficient digits (including any trailing zeros) for :class:`~decimal.Decimal`. 'f': Fixed-point notation. For a given precision ``p >= 0``, formats the number as a decimal number with exactly ``p`` digits following the decimal point. With no precision, uses a precision of ``6`` digits after the decimal point for :class:`float`, and shows all coefficient digits (including any trailing zeros) for :class:`~decimal.Decimal`. Note that in the case of a :class:`~decimal.Decimal` instance with a positive exponent, the formatted output will consist of the digits of the coefficient sequence extended by additional zeros: for example, ``format(Decimal('1.23e4'), 'f')`` gives ``'12300'``. 'g': <text as before, up to but not including the last paragraph, then:> A precision of ``0`` is treated as equivalent to a precision of ``1``. With no precision, uses a precision of ``6`` significant digits for :class:`float`, and shows all coefficient digits (including any trailing zeros) for :class:`~decimal.Decimal`. |

History | |||
---|---|---|---|

Date | User | Action | Args |

2020-11-23 18:31:45 | mark.dickinson | set | messages: + msg381686 |

2020-11-23 17:55:21 | mark.dickinson | set | messages: + msg381684 |

2020-11-23 17:24:07 | mark.dickinson | set | versions:
+ Python 3.8, Python 3.10 nosy: + docs@python messages: + msg381682 assignee: docs@python components: + Documentation, - Library (Lib) |

2020-11-23 12:56:33 | mark.dickinson | set | messages: + msg381666 |

2020-11-22 03:28:06 | eric.smith | set | nosy:
+ mark.dickinson, eric.smith messages: + msg381587 |

2020-11-21 23:29:40 | Kwpolska | create |