[Python-Dev] Progress report on PEP 242

Tim Peters tim.one@home.com
Mon, 9 Apr 2001 02:36:24 -0400


[Paul F. Dubois]
> The standard C library defines some constants in math.h that give
> the required information. I think the right thing to do is simply
> include all of those using names that make an identifiable connection
> to the standard quantities (I had five of them, but there are more).

It's in float.h in C.  Suggest looking at the new C99 std, since they did a
better job of defining these things than C89.  Luckily, they use the same
idealized model as R1MACH/D1MACH/I1MACH (in particular, they also view the
radix point as being "to the left" of all digits, so they agree on min and
max exponents).  float.h doesn't have an equivalent to your epsilonoverradix,
though).

> This begs the question of what to do if you are implementing Python
> over something other than C but the definitions in the standard C
> library are clear, so in principle this can be done.

Since virtually all boxes on Earth use IEEE-754 f.p. now, it's not like
there's a lot of variety they'll need to contend with (and, e.g., the Java
language spec requires 754 arithmetic specifically, so Jython's life can be
hardcoded).

> The default Python floating point kind would be the one used to
> return the (floating) attributes when queried, since I can't rely
> on their being any other such kind; i.e., a C double.

Hmm.  On second thought, if I do

    f = kinds.float_kind(m, n)

and it doesn't raise an exception, then surely the kind of float f() creates
*must* exist in this implementation.  Yes?  In that case f.min and f.max
(etc) can be of exactly the kind f() returns.  If you stick to C double, then
e.g. if I implement (say) IEEE double-extended, the kind object k building
such beasts couldn't return anything sensible for k.max and k.min, because C
double doesn't have enough precision or range to represent the max and min
(or epsilon or ...) double-extended values.  But a double-extended float can.

> Naming is going to be confusing no matter what we do. We're starting
> with Python "float" == C "double" == Numeric Float == typecode 'd'.
> We're doomed...

You can break that here, though.  Are these kinds utterly distinct types, or
merely different flavors of a single float type?  I assumed the latter (BTW,
the PEP really isn't clear about how kinds work in Python's type system), in
which case there's no problem saying that (for example)

    float_kind(1, 10)

builds floats of the single flavor,

    float_kind(1, 100)

builds floats of the double flavor, and

    float_kind(1, 1000)

builds floats of the extended or quad flavor.  Etc.  Since there is only one
kind of float in (base; non-NumPy) Python today, the need for distinctions
hasn't arisen.  But once a need arises, it seems downright natural to
continue calling all of them floats, but with a kind qualifier indicating
relative precision and/or range.  Then qualifiers like "single", "double",
"quad", "extended" and "unbounded" make intuitive sense to people, and that's
Good.  "float" implies something about size only to C programmers (much like
"real" implies something about size only to Fortran programmers).