reSTify PEP 242 (#323)
This commit is contained in:
parent
422c4819d4
commit
a600f25404
315
pep-0242.txt
315
pep-0242.txt
|
@ -5,231 +5,242 @@ Last-Modified: $Date$
|
|||
Author: paul@pfdubois.com (Paul F. Dubois)
|
||||
Status: Rejected
|
||||
Type: Standards Track
|
||||
Content-Type: text/x-rst
|
||||
Created: 17-Mar-2001
|
||||
Python-Version: 2.2
|
||||
Post-History: 17-Apr-2001
|
||||
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
Rationale
|
||||
=========
|
||||
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
Supported Kinds of Ints and Floats
|
||||
==================================
|
||||
|
||||
Complex numbers are treated separately below, since Python can be
|
||||
built without them.
|
||||
Complex numbers are treated separately below, since Python can be
|
||||
built without them.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.)
|
||||
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.)
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
Kind Objects
|
||||
============
|
||||
|
||||
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.).
|
||||
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.
|
||||
``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.
|
||||
``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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
Attributes of Module kinds
|
||||
==========================
|
||||
|
||||
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.
|
||||
``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.
|
||||
|
||||
float_kinds is a list of the available floating point kinds, sorted
|
||||
from lowest to highest kind.
|
||||
``float_kinds`` is a list of the available floating point kinds, sorted
|
||||
from lowest to highest kind.
|
||||
|
||||
default_int_kind is the kind object corresponding to the Python
|
||||
literal 0
|
||||
``default_int_kind`` is the kind object corresponding to the Python
|
||||
literal 0
|
||||
|
||||
default_long_kind is the kind object corresponding to the Python
|
||||
literal 0L
|
||||
``default_long_kind`` is the kind object corresponding to the Python
|
||||
literal 0L
|
||||
|
||||
default_float_kind is the kind object corresponding to the Python
|
||||
literal 0.0
|
||||
``default_float_kind`` is the kind object corresponding to the Python
|
||||
literal 0.0
|
||||
|
||||
|
||||
Complex Numbers
|
||||
===============
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
If complex numbers are supported, the following are available in
|
||||
module kinds:
|
||||
If complex numbers are supported, the following are available in
|
||||
module kinds:
|
||||
|
||||
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.
|
||||
``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.
|
||||
|
||||
complex_kinds is a list of the available complex kinds, sorted
|
||||
from lowest to highest kind.
|
||||
``complex_kinds`` is a list of the available complex kinds, sorted
|
||||
from lowest to highest kind.
|
||||
|
||||
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'.
|
||||
``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'.
|
||||
|
||||
Complex kind objects have these addition attributes:
|
||||
Complex kind objects have these addition attributes:
|
||||
|
||||
floatkind is the kind object of the corresponding float type.
|
||||
``floatkind`` is the kind object of the corresponding float type.
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
In module myprecision.py:
|
||||
In module myprecision.py::
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
In the rest of my code:
|
||||
In the rest of my code::
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
u = csingle(x + z * 1.0j)
|
||||
u2 = csingle(x+z, 1.0)
|
||||
u = csingle(x + z * 1.0j)
|
||||
u2 = csingle(x+z, 1.0)
|
||||
|
||||
Note how that entire code can then be changed to a higher
|
||||
precision by changing the arguments in myprecision.py.
|
||||
Note how that entire code can then be changed to a higher
|
||||
precision by changing the arguments in myprecision.py.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
Open Issues
|
||||
===========
|
||||
|
||||
No open issues have been raised at this time.
|
||||
No open issues have been raised at this time.
|
||||
|
||||
|
||||
Rejection
|
||||
=========
|
||||
|
||||
This PEP has been closed by the author. The kinds module will not
|
||||
be added to the standard library.
|
||||
This PEP has been closed by the author. The kinds module will not
|
||||
be added to the standard library.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
This document has been placed in the public domain.
|
||||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
|
Loading…
Reference in New Issue