# Toppling the numeric tower

Tim Hochberg tim.hochberg at ieee.org
Thu Jul 26 17:33:55 CEST 2001

```I was thinking this morning (a dangerous occupation, I know) about the
proposals to eventually unify Python's numeric model. I had all these great
ideas and I got all fired up to write a long post, then I read PEP 228 and
realized that my ideas were similar to what is in there. So instead of a
nice long post, I'll write a short one instead.

Recently Guido wrote that:

> [SNIP]
> A numeric tower
> with rationals could look like this:
>
>   int < long < rational < float < complex
[SNIP]
> Without rationals, it would look like this:
>
>   int < long < float < complex
> [SNIP]

I'm not fond of the tower method of numeric conversions. It doesn't do a
very good job of capturing the way numbers should be coerced. A better model
is a cube. Along the first axis is exactness (e.g., rational vs. float),
along the second axis complexness and along the last axis is
precision/range. The precison/range axis is kind of dicey, but thankfully
should not be needed for core Python numeric types.

For discussion purposes, I'm going to assume that some forms of PEP 237, 238
and 239 are eventually adopted. In that case, integers and longs will be
unified. The integers can then be completely emebedded into rationals. This
leaves us with just one level of precision/range for exact numbers (infinite
more or less) and one level of precision/range for inexact numbers (C
double). This allows the numeric tower to be knocked down and stirred around
to form a box:

Real      Complex
|               |
rRational cRational -- Rational (Exact)
rFloat          cFloat -- Float      (Inexact)

Coercion goes from exact to inexact and from Real to Complex.

PEP 228 proposes a single Number type with query methods to determine
whether it's real/complex, exact/inexact, etc. I'll stay with that model
since I'm not sure if builtin types can support multiple inheritance, which
is what you would need to make the above model work nicely if the rRational,
etc were to be separate classes. PEP 228 proposes the following query
methods:

>    1. isnatural()
>    2. isintegral()
>    3. isrational()
>    4. isreal()
>    5. iscomplex()
>
>    a. isexact()

This is too many. I would strip this down to

A. iscomplex()
B. isexact()
C. isintegral()

The first two correspond to the axes of the box. The last is included in the
recognition that even though integers can be nicely embedded in the
rationals, they are still very signifigant on their own and deserve their
own query function. 1 and 4 can easily be written in terms of the other
functions, so I don't think they are worth the baggage. Since all integers
and floats can be represented as rationals, I'm not sure what the point of 3
is. Maybe I'm missing something?

Anyway, that's my 2 cents on PEP 228 and the numeric tower.

Enjoy,

-tim

```