[Python-ideas] Python Numbers as Human Concept Decimal System

Oscar Benjamin oscar.j.benjamin at gmail.com
Tue Mar 11 14:04:50 CET 2014


On 11 March 2014 12:33, M.-A. Lemburg <mal at egenix.com> wrote:
> On 11.03.2014 12:46, Nick Coghlan wrote:
>>
>> ...[Oscar's proposal being that picking just one decimal floating
>>     point precision as *the* floating point precision]...
>
> I think you are leaving out one of the most important use cases
> for decimal values: data input and output.
>
> The literals would only appear in programs. However, in most use
> cases, you want to read decimal data from some source, process it
> and then write it back again. This would most likely also require
> using a few decimal literals, but the main source of decimals
> would still be constructors that you choose when writing the
> tools.

True, and the Decimal constructor does what you want. The decimal128
constructor will also do what you want provided you don't need more
than 34 digits. In my proposal you would still be able to trap Inexact
with decimal128 if desired.

> Coming back to floats and the decimal constructor:
>
> In investment banking, for example, people usually work with floats
> all the time. You only convert back to decimals at the very end of some
> calculation. The reason here being either that the calculations
> involve complex operations which are not available for decimals,
> trying to keep error intervals small, or a combination of both.
> In general, you try to use as much precision as you can afford
> (in terms of memory and speed), to keep those error intervals
> small.
>
> In accounting, you often use decimals for storing data with
> an (usually contractually or law based) agreed upon precision
> and rounding logic.

Well this is a situation where you would definitely want all of the
bells and whistles of the full Decimal module. You could still use
decimal literals in this code and they would inter-operate as
expected.

> However, there situations where you have
> to go to floats as well in order to run calculations, e.g.
> for interest, taxes, etc.
>
> In both situations, you want to have the decimal constructor
> take the float values with full precision and only then apply
> the necessary rounding to turn the value into a form which
> complies with the agreed upon rules. It's also not uncommon to
> add correctional bookings to address rounding issues explicitly
> (e.g. when calculating VAT of a large number of individual
> items).
>
> In short: you try to prevent rounding from happening as
> much as possible and when using it, you use it in a
> controlled way.
>
> Based on this, the choice to have the decimal constructor
> use full precision when reading floats is a good one, even
> though it may not feel right for the novice, the casual
> decimal user or as human concept :-)

Don't worry, I think that the suggestion to change the way that
Decimal(float) works is settled now.

> For decimal literals, I'd argue that if you enter a
> value 1.2500d, you are expecting a decimal with 4 decimal
> places precision, not 64 or 128 bits :-)

The decimal32/64/128 types can store the number in this form. Unlike
with binary floats the trailing zeros are not discarded.

> The information about the intended precision is implicit in the
> literal. You see this done in exchange rates, stock prices,
> prices at your grocery store, etc.
>
> The decimals can then be transformed into ones with higher
> precision during calculations and then possibly back to lower
> precision, but this is an explicit decision by the system doing
> the calculation.

The current behaviour will not be changed in this respect. There are
two separate things that you are referring to though. One is the
precision information associated with an individual Decimal e.g. the
number of significant digits even if some are trailing zeros. The
Decimal type preserves this information and so do the decimal64/128
formats:

>>> Decimal('10.1000')
Decimal('10.1000')
>>> Decimal('10.1000e-5')
Decimal('0.000101000')

The other precision is the limiting precision of the current
arithmetic context that is used when rounding. If you have a legal
obligation to make that rounding be just so then you're into what I
would consider to be expert usage of the decimal module.

> Anyway, just throwing in some additional entropy into this
> discussion. Probably not all that helpful, since you're already
> converging on two possible solutions :-)

Thanks!


Oscar


More information about the Python-ideas mailing list