prePEP: Decimal data type

Paul Moore pf_moore at yahoo.co.uk
Sat Nov 1 10:55:43 EST 2003


"John Roth" <newsgroups at jhrothjr.com> writes:

>> The idea is to have a Decimal data type, for every use where decimals are
>> needed but floating point is too inexact.
>>
>> The Decimal data type should support the Python standard functions and
>> operations and must comply the decimal arithmetic ANSI standard
>> X3.274-1996.
>
> Why is ANSI 274 significant? The reason I ask this is that this is
> a ***floating point*** standard, and I don't think that we particularly
> care for decimal floating point.

To be honest, I have little if any practical experience with numeric
representation issues, but it seems sensible to me to implement a
pre-existing, and presumably well thought out, standard, rather than
inventing something ad-hoc.

Of course, if the need is for something other than what ANSI 274
standardises, which seems to be what you are implying, then fair
enough. But what do you require? Infinite-precision decimal
arithmetic? If so, can you explain how you'd handle something like
1/3?

(I'm not being deliberately awkward here - my impression is that
representation issues are *hard*, and there are a lot of traps you can
fall into by oversimplifying. That's why I prefer the idea of a
pre-existing standard: it implies that *someone* has thought about the
hard stuff).

> Floating point presumes limited precision. In other words, if the actual
> number (exclusive of the location of the decimal point) gets too large,
> the least significant part is ... thrown away. I don't want that.
>
> Since we've got infinite precision integer arithmetic, going to
> limited precision decimal arithmetic is, IMNSHO, a step backwards.

Even infinite precision integers throw away information, in some
sense. Witness:

>>> 1L//3L
0L

>> When passing floating point to the constructor, what should happen?
>>
>>     j. ``Decimal(1.1) == Decimal('1.1')``
>>     k. ``Decimal(1.1) ==
>> Decimal('110000000000000008881784197001252...e-51')``
>
> Clearly, j is the correct answer. It's not all that hard to do, either.

No way. Consider:

>>> 1.1
1.1000000000000001
>>> 1.1==1.1000000000000001
True

So what should Decimal(1.1000000000000001) evaluate to? It can't be
Decimal('1.1'), as that contradicts your statement that j "clearly"
applies. But it *also* can't be Decimal('1.1000000000000001'), as then
we have the *same number* converting to two *different* Decimal
values.

As I say, it's hard.

I'd probably support Decimal(float) giving an exception, on the basis
that if you're doing this, you probably don't know what you're getting
into :-) Having a special method, say Decimal.round_float(f, digits),
is probably OK, though...

Paul.
-- 
This signature intentionally left blank




More information about the Python-list mailing list