Why not FP for Money?

Bengt Richter bokr at oz.net
Thu Sep 23 16:24:35 EDT 2004


On Thu, 23 Sep 2004 16:27:29 -0300, Carlos Ribeiro <carribeiro at gmail.com> wrote:

>On 23 Sep 2004 15:08:53 -0400, Aahz <aahz at pythoncraft.com> wrote:
>> Not sure of precise syntax (haven't tried 2.4 yet), but this should
>> work:
>> 
>>     a = decimal.from_float(35.72)
>
>I have downloaded 2.4, but couldn't install it yet. But the release
>notes states that, after long discussions, support for
>Decimal.from_float() was removed from the release, due to people being
>unable to reach a consensus on the precision to be used in the
>conversion.
>
>The problem is (to put it really simply) that 35.72 isn't really 35.72, it is:
>
>32.719999999999999
>
>What should from_float do? Truncate it to 2 digits isn't possible --
>the fact that the literal was written with two digits was lost in the
>innards of the lexical analyzer long before from_float() is called.
>And to represent it internally as 32.719999999999999 will cause
>surprises for most people; but to truncate it arbitrarily is also
>problematic. So it was removed (that's what the release notes states,
>anyway)
What I did in my exact decimal toy was mandate a rounding position parameter
(or 'all' which captures all available bits of the fp value):

 >>> from ut.exactdec import ED
 >>> ED(35.72, 2)
 ED('35.72')
 >>> ED(35.72, 6)
 ED('35.72')
 >>> ED(35.72, 'all')
 ED('35.719999999999998863131622783839702606201171875')
 >>> ED(35.72, 17)
 ED('35.71999999999999886')
 >>> ED(35.72, 16)
 ED('35.7199999999999989')
 >>> ED(35.72, 15)
 ED('35.719999999999999')
 >>> ED(35.72, 14)
 ED('35.72')

Or you can specify the number with a string literal
 ED('35.72')
 >>> ED('3.572e1')
 ED('35.72')

Interally it's represented as rational number with a decimal exponent factor,
i.e., (numerator, denominator, powerof_10)

 >>> ED('3.572e1').astuple()
 (3572, 1, -2)

>
>A native Money type, either with the $ signal ($35.72) or the suffix
>(35.72D) would not present the same issues, because the literal would
>be converted directly to the fixed point representation without the
>float intermediate step.
>
Hm, I see that D is a little too close to 0. Maybe 35.72d is easier to read,
(unlike lower case L for longs).

Regards,
Bengt Richter



More information about the Python-list mailing list