Against PEP 240

Don O'Donnell donod at home.com
Thu May 31 05:07:49 EDT 2001


Robin Becker wrote:
> 
> I am strongly opposed to the intent of PEP 240. I would prefer the
> literal floats to remain. Let those that want infinite precision pay the
> price by adding an 'R' to their literals. This PEP seems purely biassed
> towards the needs of naive programmers and I feel that is wrong; this
> whole industry has grown up with the old style (and coped quite well).
> If naive users are to be the only designers we'll end up badly.
> --
> Robin Becker

I agree with PEP 239 that Python should have a rational number type, 
but I'd like to consider the part of PEP 240, which proposes that the
literal representation for a rational should conform to the regexp: 
r"\d+\.\d*".

This representation seems to imply that all rationals must have a 
denominator which is a power of 10.  I.E., 7.35 => 735/100
How would one write the literal for (and what would be the result 
of repr() for) the rational number 353/197 for example, using the 
literal notation  d.ddddd...?  No, this representation is too limiting
for expressing the general case of rational numbers.  We need a more 
general format which allows both the numerator and denominator to be
specified.  

Since there is talk of, and a PEP 238 advocating, changing the meaning 
of the integer divide operator "/" anyway, let's make _it_ the symbol 
for expressing rationals:

>>>a = 353/197     # a is a rational number

Instead of 7.35, we would write  735/100  or, since that would get
tedious for very long divisors, how about an additional notation 
such as:  735R-2  as short-hand for  735/100
Rather than:
>>>gross_sales = 9736218425/100
>>>gross_sales = 9736218425R-2       #  or $97,362,184.25
>>>populationDensity = 150000/(1000*1000)   # 150000 per sq kilometer
>>>populationDensity = 150000R-6   # = 0.15 per sq meter

In mixed mode arithmetic, ints would be promoted to rationals, and
rationals would be promoted to floats.

This will leave the 'ddd.dddd..." notation available for representing 
fixed point numbers (either binary or decimal, to be determined), 
which I believe there is just as much, if not more, need for, than 
rationals.  I'm thinking of fixed point numbers in the COBOL sense
(PIC S9999999V99).  Whether the number is represented internally by 
a binary coded decimal (ala IBM) or by a true binary integer with 
decimal scaling (ala Univac/Unisys), really doesn't matter.  
That should be an implementation dependency, depending on
whichever suits the platform better, or more correctly, whichever
suits the C or Java language underpinnings of Python.  IIRC, from
my Intel 8086/286/386 assembler programming days (back in the '80s)
the Intel FPU had a limited decimal arithmetic instruction set as 
well as the floating point, but since I don't believe this is 
available as a C language type, it makes little difference to Python.

BOTH rational and fixed-point numbers solve the 7.35 => 7.34999... 
problem.  But it's my feeling that fixed-point numbers would also 
be a valuable addition to Python's built-in numeric types, in 
addition to the true rational type.   They would seem to have  
wider applicability (for instance, in the world of business and 
finance), than rationals, and easier to implement and more efficient 
to process than true rationals, (all it would take would be a long
integer to represent the value, and a regular int to represent the
power of 10 scale factor.  Multiplication and division would be a 
cinch and addition/subtraction would just require a simple scale
factor normalization.  It's not quite that simple with full 
rationals, I know, I wrote a Rational Class for my first Java 
course.

But, if it turns out that the efficiencies of fixed-point are
swamped out by other issues, and in the interest of keeping Python
simple and orthogonal, I wouldn't mind giving up fixed-point if we 
could have an efficient rational type.  The more I think about it,
the more it appears to me that the fixed-point type is really just
a restricted-implementation subset of the fully general rational
number type.  And I'll bet that some clever programmers out there 
will be able to optimize it to the point where I couldn't tell the
difference in performance.

In that case, as far as whether  7.35  should be a float or a 
rational, I vote for a highly optimized rational.  Especially in
view of the fact that we already have the  7.35e0  notation for
floats.  Of course, it will break a lot of existing code, so I
imagine some kind of an impact study should be done to judge the 
amount of the damage.

talking-myself-out-of-it-again-rationally y'rs,

-Don



More information about the Python-list mailing list