-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
Open
Labels
docsDocumentation in the Doc dirDocumentation in the Doc dir
Description
# Compare different precision on Decimal.
format(Decimal('0'), ".0E") '0E+0'
format(Decimal('0'), ".1E") '0.0E+1'
format(Decimal('0'), ".2E") '0.00E+2'
format(Decimal('0'), ".3E") '0.000E+3'
format(Decimal('0'), ".30E") '0.000000000000000000000000000000E+30'
format(Decimal('-0.0'), ".0E") '-0E-1'
format(Decimal('-0.0'), ".1E") '-0.0E+0'
format(Decimal('-0.0'), ".2E") '-0.00E+1'
format(Decimal('-0.0'), ".3E") '-0.000E+2'
format(Decimal('-0.0'), ".30E") '-0.000000000000000000000000000000E+29'
# Compare different 0 values.
format(0, ".3E") '0.000E+00'
format(0.0, ".3E") '0.000E+00'
format(-0.0, ".3E") '-0.000E+00'
format(0j, ".3E") '0.000E+00+0.000E+00j'
format(Decimal('0'), ".3E") '0.000E+3'
format(Decimal('-0.0'), ".3E") '-0.000E+2'
# Compare different format methods.
format(Decimal('0'), ".30E") '0.000000000000000000000000000000E+30'
format(1234512345123451234512345, ".30E") '1.234512345123451205320704000000E+24'
format(Decimal('1234512345123451234512345'), ".30E") '1.234512345123451234512345000000E+24'
"%.30E" % (Decimal('0'),) '0.000000000000000000000000000000E+00' # exponent is 0, because the value is converted to float first
"%.30E" % (1234512345123451234512345,) '1.234512345123451205320704000000E+24'
"%.30E" % (Decimal('1234512345123451234512345'),) '1.234512345123451205320704000000E+24'
It seams that precision will affect exponent.
- When formatting Decimal('0'), the exponent is equal to precision.
- When formatting Decimal('-0.0'), the exponent is equal to precision-1.
In addition to the above behavior, the exponent is not padded to
two digits, which also makes it inconsistent with the built-in types.
Although the results are numerically correct, and the document
(https://docs.python.org/3/library/string.html#format-specification-mini-language)
does not limit the exponent when the coefficient is 0.
However, this can be confusing for users.
Maybe the document needs to add a note, or change the result of Decimal type
to be consistent with built-in types.
from decimal import Decimal
templates = (
'format({v}, ".{p}E")',
# 'f"{{{v}:.{p}E}}"',
# '"{{:.{p}E}}".format({v})',
# '"%.{p}E" % ({v},)',
# 'format({v}, ".{p}e")'
# 'f"{{{v}:.{p}e}}"',
# '"{{:.{p}e}}".format({v})',
# '"%.{p}e" % ({v},)',
)
values = (
# 0,
# 0.0,
# -0.0,
# complex(0),
Decimal('0'),
Decimal('-0.0'),
# 0.001,
# Decimal('0.001'),
# 1,
# 1.0,
# Decimal('1'),
# 10,
# 10.0,
# Decimal('10'),
# 100,
# 100.0,
# Decimal('100'),
# 1234512345123451234512345,
# 1234512345123451234512345.0,
# Decimal('1234512345123451234512345'),
)
precision = (
0,
1,
2,
3,
# 4,
# 5,
# 6,
# 7,
# 8,
# 9,
# 10,
30,
# 100,
# 1000,
# 10000,
)
results = [
((expr := t.format(v=repr(v), p=p)), eval(expr))
for t in templates
for v in values
for p in precision
]
max_len_expr = max(len(expr) for expr, val in results)
for expr, val in results:
print(f"{expr}{' ' * ((max_len_expr)-len(expr))} {repr(val)}")Linked PRs
Metadata
Metadata
Assignees
Labels
docsDocumentation in the Doc dirDocumentation in the Doc dir
Projects
Status
Todo