Title: Inconsistent exponent notation formatting
Type: behavior Stage: resolved
Components: Versions: Python 3.7, Python 3.6, Python 3.5, Python 2.7
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: eric.smith, mark.dickinson, seperman, skrah, xtreak
Priority: normal Keywords:

Created on 2019-04-13 00:36 by seperman, last changed 2019-04-14 08:32 by mark.dickinson. This issue is now closed.

Messages (5)
msg340136 - (view) Author: Sep Dehpour (seperman) Date: 2019-04-13 00:36
Floats and Decimals have inconsistent exponent notation formatting:

>>> '{:.5e}'.format(Decimal('2.0001'))
>>> '{:.5e}'.format(2.0001)

This is causing issues for us since we use the scientific notation formatted string of numbers to compare them. Between decimals and floats, one produces '+0' while the other one produces '+00'
msg340181 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2019-04-14 05:55
Seems this has tests at . I also noticed the below. Considering this is the behavior from 2.7 is it a conscious design decision?

>>> '{:.5e}'.format(1.23457e+8)
>>> '{:.5e}'.format(decimal.Decimal(1.23457e+8))
msg340189 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2019-04-14 07:51
Yes, I'd think the decisions are deliberate.

Floats follow printf(), this is from the manual for 'e':

  "The exponent always contains at least two digits; if the value is zero, the exponent is 00."

And decimal follows the specification at .

Of course Python's format() could decide to override the specification, but it would lead to more code complexity.

But I don't think that mixing float/decimal output is a common use case.
msg340194 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2019-04-14 08:19
Indeed it's deliberate. When the Decimal type was introduced, the "at least two exponent digits" behaviour of float formatting was already long established. But the specification that the Decimal type was based on (and the extensive test cases from the same source) use the minimum number of exponent digits instead.

If we want to make the two things consistent, that means either deliberately introducing incompatibilities with the Decimal specification, or changing long-standing behaviour for float.

There's no reason in principle that we couldn't modify the float formatting to use a single digit in the exponent (assuming that exponent is smaller than 10 in absolute value). I'd expect that that would upset more people than it would help, though.

My guess is that the "at least 2 digits" rule in C99 7.24.2 is there to make it easier to align tables of values formatted in scientific notation. I can't think of another reason for force at least two digits.

For your use-case, could you convert all `float` objects to `Decimal` objects before comparison? The float to Decimal conversion doesn't lose any information (unlike the reverse conversion).

Closing this as "not a bug". There's certainly room for proposing and discussing changes to the behaviour, but that's probably best done on the python-ideas mailing list rather than the bug tracker.
msg340195 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2019-04-14 08:32
FWIW, here's where that "at least two digits" is encoded in the CPython source:

*If* we wanted to, it would be an easy change to get rid of the extra leading exponent zeros.
Date User Action Args
2019-04-14 08:32:26mark.dickinsonsetmessages: + msg340195
2019-04-14 08:19:31mark.dickinsonsetstatus: open -> closed
resolution: not a bug
messages: + msg340194

stage: resolved
2019-04-14 07:51:26skrahsetmessages: + msg340189
2019-04-14 05:55:10xtreaksetnosy: + xtreak
messages: + msg340181
2019-04-13 01:01:38eric.smithsetnosy: + mark.dickinson, eric.smith, skrah
2019-04-13 00:36:55sepermancreate