2001-03-20 00:29:16 -05:00
|
|
|
PEP: 242
|
|
|
|
Title: Numeric Kinds
|
2022-10-05 12:48:43 -04:00
|
|
|
Author: Paul F. Dubois <paul@pfdubois.com>
|
2024-04-14 09:35:25 -04:00
|
|
|
Status: Withdrawn
|
2001-03-20 00:29:16 -05:00
|
|
|
Type: Standards Track
|
|
|
|
Created: 17-Mar-2001
|
|
|
|
Python-Version: 2.2
|
2001-04-17 18:12:46 -04:00
|
|
|
Post-History: 17-Apr-2001
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2024-04-14 09:35:25 -04:00
|
|
|
.. withdrawn::
|
2024-04-14 16:08:31 -04:00
|
|
|
|
|
|
|
The kinds module will not be added to the standard library.
|
2024-04-14 09:35:25 -04:00
|
|
|
|
|
|
|
There was no opposition to the proposal but only mild interest in
|
|
|
|
using it, not enough to justify adding the module to the standard
|
|
|
|
library. Instead, it will be made available as a separate
|
|
|
|
distribution item at the Numerical Python site. At the next
|
|
|
|
release of Numerical Python, it will no longer be a part of the
|
|
|
|
Numeric distribution.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
|
|
|
Abstract
|
2017-08-15 17:24:15 -04:00
|
|
|
========
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
This proposal gives the user optional control over the precision
|
|
|
|
and range of numeric computations so that a computation can be
|
|
|
|
written once and run anywhere with at least the desired precision
|
|
|
|
and range. It is backward compatible with existing code. The
|
|
|
|
meaning of decimal literals is clarified.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
Rationale
|
2017-08-15 17:24:15 -04:00
|
|
|
=========
|
|
|
|
|
|
|
|
Currently it is impossible in every language except Fortran 90 to
|
|
|
|
write a program in a portable way that uses floating point and
|
|
|
|
gets roughly the same answer regardless of platform -- or refuses
|
|
|
|
to compile if that is not possible. Python currently has only one
|
|
|
|
floating point type, equal to a C double in the C implementation.
|
|
|
|
|
|
|
|
No type exists corresponding to single or quad floats. It would
|
|
|
|
complicate the language to try to introduce such types directly
|
|
|
|
and their subsequent use would not be portable. This proposal is
|
|
|
|
similar to the Fortran 90 "kind" solution, adapted to the Python
|
|
|
|
environment. With this facility an entire calculation can be
|
|
|
|
switched from one level of precision to another by changing a
|
|
|
|
single line. If the desired precision does not exist on a
|
|
|
|
particular machine, the program will fail rather than get the
|
|
|
|
wrong answer. Since coding in this style would involve an early
|
|
|
|
call to the routine that will fail, this is the next best thing to
|
|
|
|
not compiling.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
|
|
|
|
2001-04-17 12:31:14 -04:00
|
|
|
Supported Kinds of Ints and Floats
|
2017-08-15 17:24:15 -04:00
|
|
|
==================================
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
Complex numbers are treated separately below, since Python can be
|
|
|
|
built without them.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
Each Python compiler may define as many "kinds" of integer and
|
|
|
|
floating point numbers as it likes, except that it must support at
|
|
|
|
least two kinds of integer corresponding to the existing int and
|
|
|
|
long, and must support at least one kind of floating point number,
|
|
|
|
equivalent to the present float.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
The range and precision of these required kinds are processor
|
|
|
|
dependent, as at present, except for the "long integer" kind,
|
|
|
|
which can hold an arbitrary integer.
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
The built-in functions ``int()``, ``long()``, and ``float()`` convert inputs
|
|
|
|
to these default kinds as they do at present. (Note that a
|
|
|
|
Unicode string is actually a different "kind" of string and that a
|
|
|
|
sufficiently knowledgeable person might be able to expand this PEP
|
|
|
|
to cover that case.)
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
Within each type (integer, floating) the compiler supports a
|
|
|
|
linearly-ordered set of kinds, with the ordering determined by the
|
|
|
|
ability to hold numbers of an increased range and/or precision.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
Kind Objects
|
2017-08-15 17:24:15 -04:00
|
|
|
============
|
|
|
|
|
|
|
|
Two new standard functions are defined in a module named "kinds".
|
|
|
|
They return callable objects called kind objects. Each int or
|
|
|
|
floating kind object f has the signature ``result = f(x)``, and each
|
|
|
|
complex kind object has the signature ``result = f(x, y=0.)``.
|
|
|
|
|
|
|
|
``int_kind(n)``
|
|
|
|
For an integer argument ``n >= 1``, return a callable object whose
|
|
|
|
result is an integer kind that will hold an integer number in
|
|
|
|
the open interval (``-10**n``, ``10**n``). The kind object accepts
|
|
|
|
arguments that are integers including longs. If ``n == 0``,
|
|
|
|
returns the kind object corresponding to the Python literal 0.
|
|
|
|
|
|
|
|
``float_kind(nd, n)``
|
|
|
|
For ``nd >= 0`` and ``n >= 1``, return a callable object whose result
|
|
|
|
is a floating point kind that will hold a floating-point
|
|
|
|
number with at least nd digits of precision and a base-10
|
|
|
|
exponent in the closed interval ``[-n, n]``. The kind object
|
|
|
|
accepts arguments that are integer or float.
|
|
|
|
|
|
|
|
If nd and n are both zero, returns the kind object
|
|
|
|
corresponding to the Python literal 0.0.
|
|
|
|
|
|
|
|
The compiler will return a kind object corresponding to the least
|
|
|
|
of its available set of kinds for that type that has the desired
|
|
|
|
properties. If no kind with the desired qualities exists in a
|
|
|
|
given implementation an ``OverflowError`` exception is thrown. A kind
|
|
|
|
function converts its argument to the target kind, but if the
|
|
|
|
result does not fit in the target kind's range, an ``OverflowError``
|
|
|
|
exception is thrown.
|
|
|
|
|
|
|
|
Besides their callable behavior, kind objects have attributes
|
|
|
|
giving the traits of the kind in question.
|
|
|
|
|
|
|
|
1. ``name`` is the name of the kind. The standard kinds are called
|
|
|
|
int, long, double.
|
|
|
|
|
|
|
|
2. ``typecode`` is a single-letter string that would be appropriate
|
|
|
|
for use with ``Numeric`` or module ``array`` to form an array of this
|
|
|
|
kind. The standard types' typecodes are 'i', 'O', 'd'
|
|
|
|
respectively.
|
|
|
|
|
|
|
|
3. Integer kinds have these additional attributes: ``MAX``, equal to
|
|
|
|
the maximum permissible integer of this kind, or ``None`` for the
|
|
|
|
long kind. ``MIN``, equal to the most negative permissible integer
|
|
|
|
of this kind, or ``None`` for the long kind.
|
|
|
|
|
|
|
|
4. Float kinds have these additional attributes whose properties
|
|
|
|
are equal to the corresponding value for the corresponding C
|
|
|
|
type in the standard header file "float.h". ``MAX``, ``MIN``, ``DIG``,
|
|
|
|
``MANT_DIG``, ``EPSILON``, ``MAX_EXP``, ``MAX_10_EXP``, ``MIN_EXP``,
|
|
|
|
``MIN_10_EXP``, ``RADIX``, ``ROUNDS``
|
|
|
|
(== ``FLT_RADIX``, ``FLT_ROUNDS`` in float.h). These
|
|
|
|
values are of type integer except for ``MAX``, ``MIN``, and ``EPSILON``,
|
|
|
|
which are of the Python floating type to which the kind
|
|
|
|
corresponds.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
|
|
|
|
2001-04-17 12:31:14 -04:00
|
|
|
Attributes of Module kinds
|
2017-08-15 17:24:15 -04:00
|
|
|
==========================
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
``int_kinds`` is a list of the available integer kinds, sorted from lowest
|
|
|
|
to highest kind. By definition, ``int_kinds[-1]`` is the long kind.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
``float_kinds`` is a list of the available floating point kinds, sorted
|
|
|
|
from lowest to highest kind.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
``default_int_kind`` is the kind object corresponding to the Python
|
|
|
|
literal 0
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
``default_long_kind`` is the kind object corresponding to the Python
|
|
|
|
literal 0L
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
``default_float_kind`` is the kind object corresponding to the Python
|
|
|
|
literal 0.0
|
2001-03-20 00:29:16 -05:00
|
|
|
|
|
|
|
|
2001-04-17 12:31:14 -04:00
|
|
|
Complex Numbers
|
2017-08-15 17:24:15 -04:00
|
|
|
===============
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
If supported, complex numbers have real and imaginary parts that
|
|
|
|
are floating-point numbers with the same kind. A Python compiler
|
|
|
|
must support a complex analog of each floating point kind it
|
|
|
|
supports, if it supports complex numbers at all.
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
If complex numbers are supported, the following are available in
|
|
|
|
module kinds:
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
``complex_kind(nd, n)``
|
|
|
|
Return a callable object whose result is a complex kind that
|
|
|
|
will hold a complex number each of whose components (.real,
|
|
|
|
.imag) is of kind ``float_kind(nd, n)``. The kind object will
|
|
|
|
accept one argument that is of any integer, real, or complex
|
|
|
|
kind, or two arguments, each integer or real.
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
``complex_kinds`` is a list of the available complex kinds, sorted
|
|
|
|
from lowest to highest kind.
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
``default_complex_kind`` is the kind object corresponding to the
|
|
|
|
Python literal 0.0j. The name of this kind
|
|
|
|
is doublecomplex, and its typecode is 'D'.
|
2017-03-24 17:11:33 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
Complex kind objects have these addition attributes:
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
``floatkind`` is the kind object of the corresponding float type.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
Examples
|
2017-08-15 17:24:15 -04:00
|
|
|
========
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
In module myprecision.py::
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
import kinds
|
|
|
|
tinyint = kinds.int_kind(1)
|
|
|
|
single = kinds.float_kind(6, 90)
|
|
|
|
double = kinds.float_kind(15, 300)
|
|
|
|
csingle = kinds.complex_kind(6, 90)
|
2017-03-24 17:11:33 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
In the rest of my code::
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
from myprecision import tinyint, single, double, csingle
|
|
|
|
n = tinyint(3)
|
|
|
|
x = double(1.e20)
|
|
|
|
z = 1.2
|
|
|
|
# builtin float gets you the default float kind, properties unknown
|
|
|
|
w = x * float(x)
|
|
|
|
# but in the following case we know w has kind "double".
|
|
|
|
w = x * double(z)
|
2001-04-17 12:31:14 -04:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
u = csingle(x + z * 1.0j)
|
|
|
|
u2 = csingle(x+z, 1.0)
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
Note how that entire code can then be changed to a higher
|
|
|
|
precision by changing the arguments in myprecision.py.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
Comment: note that you aren't promised that single != double; but
|
|
|
|
you are promised that ``double(1.e20)`` will hold a number with 15
|
|
|
|
decimal digits of precision and a range up to ``10**300`` or that the
|
|
|
|
``float_kind`` call will fail.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
Open Issues
|
2017-08-15 17:24:15 -04:00
|
|
|
===========
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
No open issues have been raised at this time.
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2003-02-14 09:50:54 -05:00
|
|
|
|
2001-03-20 00:29:16 -05:00
|
|
|
Copyright
|
2017-08-15 17:24:15 -04:00
|
|
|
=========
|
2001-03-20 00:29:16 -05:00
|
|
|
|
2017-08-15 17:24:15 -04:00
|
|
|
This document has been placed in the public domain.
|