GH-105774: Clarify operation of normalize() (GH-106093)

This commit is contained in:
Raymond Hettinger 2023-06-26 23:12:22 -05:00 committed by GitHub
parent 0345b0c2bb
commit a8210b6df1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -743,12 +743,23 @@ Decimal objects
.. method:: normalize(context=None)
Normalize the number by stripping the rightmost trailing zeros and
converting any result equal to ``Decimal('0')`` to
``Decimal('0e0')``. Used for producing canonical values for attributes
of an equivalence class. For example, ``Decimal('32.100')`` and
``Decimal('0.321000e+2')`` both normalize to the equivalent value
``Decimal('32.1')``.
Used for producing canonical values of an equivalence
class within either the current context or the specified context.
This has the same semantics as the unary plus operation, except that if
the final result is finite it is reduced to its simplest form, with all
trailing zeros removed and its sign preserved. That is, while the
coefficient is non-zero and a multiple of ten the coefficient is divided
by ten and the exponent is incremented by 1. Otherwise (the coefficient is
zero) the exponent is set to 0. In all cases the sign is unchanged.
For example, ``Decimal('32.100')`` and ``Decimal('0.321000e+2')`` both
normalize to the equivalent value ``Decimal('32.1')``.
Note that rounding is applied *before* reducing to simplest form.
In the latest versions of the specification, this operation is also known
as ``reduce``.
.. method:: number_class(context=None)
@ -2078,6 +2089,26 @@ representative:
>>> [v.normalize() for v in values]
[Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]
Q. When does rounding occur in a computation?
A. It occurs *after* the computation. The philosophy of the decimal
specification is that numbers are considered exact and are created
independent of the current context. They can even have greater
precision than current context. Computations process with those
exact inputs and then rounding (or other context operations) is
applied to the *result* of the computation::
>>> getcontext().prec = 5
>>> pi = Decimal('3.1415926535') # More than 5 digits
>>> pi # All digits are retained
Decimal('3.1415926535')
>>> pi + 0 # Rounded after an addition
Decimal('3.1416')
>>> pi - Decimal('0.00005') # Subtract unrounded numbers, then round
Decimal('3.1415')
>>> pi + 0 - Decimal('0.00005'). # Intermediate values are rounded
Decimal('3.1416')
Q. Some decimal values always print with exponential notation. Is there a way
to get a non-exponential representation?