[Python-Dev] RE: Adding decimal (aka FixedPoint) numbers to Python
Tim Peters
tim.one@comcast.net
Mon, 16 Dec 2002 01:48:01 -0500
[Michael McLay]
> ...
> The semantics of the precision parameter may be incorrect because
> it is only addressing the precision of the fraction part of the
> number.
That's why the module was called FixedPoint.
> Shouldn't it reflect the number of significant digits?
That would be more appropriate to a floating point scheme. Aahz has been
working on a Python implementation of Mike Cowlishaw's hybrid proposal:
http://www2.hursley.ibm.com/decimal/
for about, oh, fifteen years now <wink>.
> ...
> >>> 3.03e5d
> 303000.00d
>
> The representation is incorrect. It should have returned 3.03e5d
> but it padded the result with bogus zeros.
It seems you don't really want a fixed-point type. The FixedPoint
constructor avoided this rat hole by making the user be explicit about the
fixed number of fractional digits (or accept the default 2).
> ...
> Python also supports fixed point decimal numbers. These numbers
> do not suffer from the somewhat random roundoff errors that can occur
> with binary floating point numbers.
Yes they do. In fact, roundoff error in decimal arithmetic is actually a
little *worse* than in binary arithmetic. The saving grace of decimal
arithmetic has to do with representation error, not with roundoff error:
decimal numbers are exactly representable in a decimal arithmetic system,
but "almost all" decimal numbers can't be represented exactly in a binary
arithmetic system. In addition, under FixedPoint's unusual "unbounded
before the decimal point, fixed # of digits after, and when mixing precision
the result gets the larger of the input precisions" rules, all of the
following are always exact operations:
to_decimal_string
from_decimal_string
+ - *
mod
divmod
Take away the "unbounded before the decimal point" and/or the "result
inherits the larger input precision" rules and the arithmetic operations
suffer roundoff errors, just as bad (actually a little worse) as binary
fixed-#-of-bits fp suffers.
> ...
>>> 3.3d + decimal(3.03,3)
> 6.330d
> >>> decimal(1.1, 16)
> 1.1000000000000001d
> >>>
> The builtin decimal constructor provides a means for converting
> float and int types to decimal types. Since floats are approximations
> of decimal floating point numbers there are often roundoff errors
> introduced by using floats.
> (The 1 in the last place of the conversion of 1.1 with 16 digits
> is a binary round off error.)
That's really representation error. Until the distinction becomes clear,
you'll keep believing that decimal arithmetic is somehow better <wink>.
[martin@v.loewis.de]
> ...
> It also appears that a decimal type feature in the language
> will/should interact with a rational type.
Possibly. This is easy for FixedPoint, becauase internally they're actually
unbounded rationals in unnormalized form, with the denominator constrained
to be an exact power of 10.
[bsder@mail.allcaps.org]
> ...
> 2) There are official/semi-official standards for decimal floating-
> point arithmetic. (IEEE 854 + ANSI X3.274 + ECMA 334) The
> fixedpoint module seems to comply with these standards only at the
> most basic levels.
To the extent that it complies with them at all, that's an accident. See
above: the overwhelming design goal of FixedPoint was to eliminate rounding
error entirely in the basic arithmetic operations. That can't be achieved
for division, but can be (and was) for the rest. Division settled for
as-if-to-infinite-precision single-rounding to-nearest/even, which is the
least error-prone way to do it when you *have* to lose information.
[Brett Cannon]
> ...
> It is still going to take someone to champion the module to get BDFL
> pronouncment from Guido autonomously or get enough people to rally
> behind to put pressure on Guido to let it in.
Guido already agreed to fold FixedPoint into 2.3, provided someone other
than me do the work <wink>. Doug Fort has done a great job on it (including
LaTeX docs, Fred!), and we're just missing someone with the time/desire to
do final integration.
That's independent of Michael's patch, of course. The FixedPoint module is
just another library module.
> What I would like to know is if Tim ever pushed to get the module in,
> and if not, why?
I've never pushed for any of my modules to get in. If a module attracts
enough users, it eventually becomes clear that it should go in, else it
becomes clear that it should remain out. FixedPoint has had a small but
indecently grateful <wink> and growing audience for several years now.
> Since he is the original author I assume he felt some reason
> to write it (although it quite easily be "I was bored" <wink>) and yet
> didn't feel like trying to get it into the stdlib.
At the time I wrote it, numerically incorrect "fixed point" / "BCD" /
"decimal" classes were common on c.l.py. Simulating decimal arithmetic
correctly isn't difficult if you've got the right background for it, but
most people who want it don't have the right background to implement it.
OTOH, I had a crushingly strong background to implement it, but didn't want
it for myself. So after years of pointing out errors in flawed modules of
this kind, it dawned on me that I could save more time overall by writing a
correct implementation, as surprise-free as numerically possible. That's
all there was to it, and you haven't seen a bad decimal module on c.l.py
ever since <wink>.
If Python were to grow a native decimal type, I'd rather move to Cowlishaw's
design, because it has the best shot at becoming a standard influential
enough to sway HW design (decimal fp in HW wouldn't be notably more
expensive or slower than binary fp in HW, given current chip capacities;
this was a much bigger deal when chip real estate was scarce).
>> The syntax change is primarily to make Python more appealing to
>> professions that require the semantics of fixed point decimal numbers.
> I understand that, but who knows how many of those types of users are
> out there (current and potentiol).
"Do applications actually use decimal data?" from Cowlishaw's FAQ should go
a way toward answering that:
http://www2.hursley.ibm.com/decimal/decifaq.html