On 11 March 2014 12:33, M.-A. Lemburg email@example.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 :-)