PEP 327: Decimal Data Type

Paul Moore pf_moore at yahoo.co.uk
Mon Feb 2 12:52:35 EST 2004


Josiah Carlson <jcarlson at nospam.uci.edu> writes:

> One must remember to normalize on initialization, but that's not
> difficult.  Functionally that's how my rational turned out.  It wasn't
> terribly full featured, but it worked well for what I was doing.

Straightforward rational implementations *are* easy. But when you
start to look at some of the more subtle numerical issues, life
rapidly gets hard.

The key point (easy enough with Python, but bear with me) is that the
numerator and denominator *must* be infinite-precision integers. 
Otherwise, rationals have as many rounding and representational issues
as floating point numbers, and the characteristics of the problems
differ in ways that make them *less* usable without specialist
knowledge, not more.

With Python, this isn't an onerous requirement, as Python Longs fit
the bill nicely. But the next decision you have to make is how often
to normalise. You imply (in your comment above) that you should only
normalise on initialisation, but if you do that, your representation
rapidly blows up, in terms of space used. Sure,
8761348763287654786543876543/17522697526575309573087753086 is the same
as 1/2, but the former uses a lot more space, and is going to be
slower to compute with.

But if you normalise every time, some theoretically simple operations
can become relatively very expensive in terms of time. (Basically,
things like addition, which suddenly require a GCD calculation).

So you have to work out a good tradeoff, which isn't easy.

There are other issues to consider, but that should be enough to
demonstrate the sort of issues an "industrial strength" rational
implementation must address.

Of course, this isn't to say that every implementation *needs* to be
industrial-strength. Only the user can say what's good enough for his
needs.

Paul.
-- 
This signature intentionally left blank



More information about the Python-list mailing list