[Python-Dev] Fixed-point numeric type

Tim Peters tim.one@comcast.net
Wed, 05 Feb 2003 10:49:36 -0500


[Ka-Ping Yee]
> I know no one asked for my opinion, but if you will indulge me
> for a moment -- i think the most important concern is to keep the
> type simple, minimal, and above all *immutable*.
>
> Thus:
>
> 1.  Prevent setting of attributes.

Good idea.

> 2.  Turn 'precision' into a read-only attribute.  To set precision,
>     just make a new number with decimal(x, new_precision).

The existing set_precision() name still seems fine, though.  It's not
necessarily a "new" precision; set_precision says what it means.

> 3.  But don't call it 'precision'.  The word 'precision' usually
>     means either the total number of significant digits, or the
>     least significant distinguishable unit.  What we're talking
>     about (number of digits after the decimal point) is neither.
>     I believe the correct term is 'scale' (from SQL).  See also
>     http://www2.hursley.ibm.com/decimal/.

Opposed.  Users had no trouble understanding what precision means in this
context (the module has been in use for a few years).

> 4.  Get rid of copy(); it's unnecessary if you're immutable.

Agreed.

> 5.  Get rid of 'frac()'.  I don't see how it would be needed
>     very often, and it's easy to do x - long(x).

Don't care much, but gratuitous fiddling will turn this into a bottomless
pit.

> That leaves a simple immutable numeric type with no public methods

"no public methods" is a non-goal to me.

> and just one attribute -- hence the least possible burden on a
> future version of Python, if this type eventually becomes built-in.
> (And the least possible burden is a good goal in general anyway.)

I hope that an implementation of Mike Cowlishaw's nascent standard gets that
honor instead.

> Also:
>
> 6.  No global mutable state.  That means no global settings for
>     default precision or rounding mode.  Either pick a standard
>     precision or always require the second constructor argument.
>     Rounding mode is a tougher problem; i see two solutions:
>
>     (a) Eliminate variable rounding; always round half to even.

Too unrealistic to consider -- a slew of silly rounding modes is a
requirement for commercial use.

>     (b) Set rounding function as an attribute of the number.

Bleech.

>         Operators use the rounding function of the first operand.
>         This lets modules control module-local rounding behaviour
>         if they really want to do so, without interfering with
>         the rest of the program.
>
> This may sound like a harsh requirement, but i am convinced that
> global mutable settings will cause nightmares for people who try
> to make their modules and programs interoperate.

Tough luck.  Practicality beats purity here:  the pure solution is to pass a
"numeric context" object to each operation, which some implementations
actually require.  The resulting source code is tedious and unreadable.  The
practical alternative is what you live with every day in FP arithmetic, yet
don't even notice:  thread-local state holding the current IEEE-754 rounding
mode and precision control (etc) settings, implicitly an input to every
operation (and assorted 754 status flags are also implicitly outputs from
every operation).  It works fine, but requires some care in programs living
on the edge.  People will screw it sometimes, but so it goes.