CINXE.COM

PEP 242 – Numeric Kinds | peps.python.org

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="color-scheme" content="light dark"> <title>PEP 242 – Numeric Kinds | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0242/"> <link rel="stylesheet" href="../_static/style.css" type="text/css"> <link rel="stylesheet" href="../_static/mq.css" type="text/css"> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light"> <link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark"> <link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss"> <meta property="og:title" content='PEP 242 – Numeric Kinds | peps.python.org'> <meta property="og:description" content="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. ..."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0242/"> <meta property="og:site_name" content="Python Enhancement Proposals (PEPs)"> <meta property="og:image" content="https://peps.python.org/_static/og-image.png"> <meta property="og:image:alt" content="Python PEPs"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> <meta name="description" content="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. ..."> <meta name="theme-color" content="#3776ab"> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all"> <title>Following system colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="9"></circle> <path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path> </svg> </symbol> <symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all"> <title>Selected dark colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path> </svg> </symbol> <symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all"> <title>Selected light colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </symbol> </svg> <script> document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto" </script> <section id="pep-page-section"> <header> <h1>Python Enhancement Proposals</h1> <ul class="breadcrumbs"> <li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li> <li><a href="../pep-0000/">PEP Index</a> &raquo; </li> <li>PEP 242</li> </ul> <button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())"> <svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg> <span class="visually-hidden">Toggle light / dark / auto colour theme</span> </button> </header> <article> <section id="pep-content"> <h1 class="page-title">PEP 242 – Numeric Kinds</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Paul F. Dubois &lt;paul&#32;&#97;t&#32;pfdubois.com&gt;</dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Removed from consideration by sponsor or authors">Withdrawn</abbr></dd> <dt class="field-odd">Type<span class="colon">:</span></dt> <dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd> <dt class="field-even">Created<span class="colon">:</span></dt> <dd class="field-even">17-Mar-2001</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">2.2</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even">17-Apr-2001</dd> </dl> <hr class="docutils" /> <section id="contents"> <details><summary>Table of Contents</summary><ul class="simple"> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#supported-kinds-of-ints-and-floats">Supported Kinds of Ints and Floats</a></li> <li><a class="reference internal" href="#kind-objects">Kind Objects</a></li> <li><a class="reference internal" href="#attributes-of-module-kinds">Attributes of Module kinds</a></li> <li><a class="reference internal" href="#complex-numbers">Complex Numbers</a></li> <li><a class="reference internal" href="#examples">Examples</a></li> <li><a class="reference internal" href="#open-issues">Open Issues</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> </details></section> <div class="pep-banner sticky-banner deprecated withdrawn admonition important"> <p class="admonition-title">Important</p> <p>This PEP has been withdrawn.</p> <p class="close-button">×</p> <p>The kinds module will not be added to the standard library.</p> <p>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.</p> <p></p> </div> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>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.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>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.</p> <p>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.</p> </section> <section id="supported-kinds-of-ints-and-floats"> <h2><a class="toc-backref" href="#supported-kinds-of-ints-and-floats" role="doc-backlink">Supported Kinds of Ints and Floats</a></h2> <p>Complex numbers are treated separately below, since Python can be built without them.</p> <p>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.</p> <p>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.</p> <p>The built-in functions <code class="docutils literal notranslate"><span class="pre">int()</span></code>, <code class="docutils literal notranslate"><span class="pre">long()</span></code>, and <code class="docutils literal notranslate"><span class="pre">float()</span></code> 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.)</p> <p>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.</p> </section> <section id="kind-objects"> <h2><a class="toc-backref" href="#kind-objects" role="doc-backlink">Kind Objects</a></h2> <p>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 <code class="docutils literal notranslate"><span class="pre">result</span> <span class="pre">=</span> <span class="pre">f(x)</span></code>, and each complex kind object has the signature <code class="docutils literal notranslate"><span class="pre">result</span> <span class="pre">=</span> <span class="pre">f(x,</span> <span class="pre">y=0.)</span></code>.</p> <dl> <dt><code class="docutils literal notranslate"><span class="pre">int_kind(n)</span></code></dt><dd>For an integer argument <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">&gt;=</span> <span class="pre">1</span></code>, return a callable object whose result is an integer kind that will hold an integer number in the open interval (<code class="docutils literal notranslate"><span class="pre">-10**n</span></code>, <code class="docutils literal notranslate"><span class="pre">10**n</span></code>). The kind object accepts arguments that are integers including longs. If <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">==</span> <span class="pre">0</span></code>, returns the kind object corresponding to the Python literal 0.</dd> <dt><code class="docutils literal notranslate"><span class="pre">float_kind(nd,</span> <span class="pre">n)</span></code></dt><dd>For <code class="docutils literal notranslate"><span class="pre">nd</span> <span class="pre">&gt;=</span> <span class="pre">0</span></code> and <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">&gt;=</span> <span class="pre">1</span></code>, 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 <code class="docutils literal notranslate"><span class="pre">[-n,</span> <span class="pre">n]</span></code>. The kind object accepts arguments that are integer or float.<p>If nd and n are both zero, returns the kind object corresponding to the Python literal 0.0.</p> </dd> </dl> <p>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 <code class="docutils literal notranslate"><span class="pre">OverflowError</span></code> 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 <code class="docutils literal notranslate"><span class="pre">OverflowError</span></code> exception is thrown.</p> <p>Besides their callable behavior, kind objects have attributes giving the traits of the kind in question.</p> <ol class="arabic simple"> <li><code class="docutils literal notranslate"><span class="pre">name</span></code> is the name of the kind. The standard kinds are called int, long, double.</li> <li><code class="docutils literal notranslate"><span class="pre">typecode</span></code> is a single-letter string that would be appropriate for use with <code class="docutils literal notranslate"><span class="pre">Numeric</span></code> or module <code class="docutils literal notranslate"><span class="pre">array</span></code> to form an array of this kind. The standard types’ typecodes are ‘i’, ‘O’, ‘d’ respectively.</li> <li>Integer kinds have these additional attributes: <code class="docutils literal notranslate"><span class="pre">MAX</span></code>, equal to the maximum permissible integer of this kind, or <code class="docutils literal notranslate"><span class="pre">None</span></code> for the long kind. <code class="docutils literal notranslate"><span class="pre">MIN</span></code>, equal to the most negative permissible integer of this kind, or <code class="docutils literal notranslate"><span class="pre">None</span></code> for the long kind.</li> <li>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”. <code class="docutils literal notranslate"><span class="pre">MAX</span></code>, <code class="docutils literal notranslate"><span class="pre">MIN</span></code>, <code class="docutils literal notranslate"><span class="pre">DIG</span></code>, <code class="docutils literal notranslate"><span class="pre">MANT_DIG</span></code>, <code class="docutils literal notranslate"><span class="pre">EPSILON</span></code>, <code class="docutils literal notranslate"><span class="pre">MAX_EXP</span></code>, <code class="docutils literal notranslate"><span class="pre">MAX_10_EXP</span></code>, <code class="docutils literal notranslate"><span class="pre">MIN_EXP</span></code>, <code class="docutils literal notranslate"><span class="pre">MIN_10_EXP</span></code>, <code class="docutils literal notranslate"><span class="pre">RADIX</span></code>, <code class="docutils literal notranslate"><span class="pre">ROUNDS</span></code> (== <code class="docutils literal notranslate"><span class="pre">FLT_RADIX</span></code>, <code class="docutils literal notranslate"><span class="pre">FLT_ROUNDS</span></code> in float.h). These values are of type integer except for <code class="docutils literal notranslate"><span class="pre">MAX</span></code>, <code class="docutils literal notranslate"><span class="pre">MIN</span></code>, and <code class="docutils literal notranslate"><span class="pre">EPSILON</span></code>, which are of the Python floating type to which the kind corresponds.</li> </ol> </section> <section id="attributes-of-module-kinds"> <h2><a class="toc-backref" href="#attributes-of-module-kinds" role="doc-backlink">Attributes of Module kinds</a></h2> <p><code class="docutils literal notranslate"><span class="pre">int_kinds</span></code> is a list of the available integer kinds, sorted from lowest to highest kind. By definition, <code class="docutils literal notranslate"><span class="pre">int_kinds[-1]</span></code> is the long kind.</p> <p><code class="docutils literal notranslate"><span class="pre">float_kinds</span></code> is a list of the available floating point kinds, sorted from lowest to highest kind.</p> <p><code class="docutils literal notranslate"><span class="pre">default_int_kind</span></code> is the kind object corresponding to the Python literal 0</p> <p><code class="docutils literal notranslate"><span class="pre">default_long_kind</span></code> is the kind object corresponding to the Python literal 0L</p> <p><code class="docutils literal notranslate"><span class="pre">default_float_kind</span></code> is the kind object corresponding to the Python literal 0.0</p> </section> <section id="complex-numbers"> <h2><a class="toc-backref" href="#complex-numbers" role="doc-backlink">Complex Numbers</a></h2> <p>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.</p> <p>If complex numbers are supported, the following are available in module kinds:</p> <dl class="simple"> <dt><code class="docutils literal notranslate"><span class="pre">complex_kind(nd,</span> <span class="pre">n)</span></code></dt><dd>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 <code class="docutils literal notranslate"><span class="pre">float_kind(nd,</span> <span class="pre">n)</span></code>. The kind object will accept one argument that is of any integer, real, or complex kind, or two arguments, each integer or real.</dd> </dl> <p><code class="docutils literal notranslate"><span class="pre">complex_kinds</span></code> is a list of the available complex kinds, sorted from lowest to highest kind.</p> <p><code class="docutils literal notranslate"><span class="pre">default_complex_kind</span></code> is the kind object corresponding to the Python literal 0.0j. The name of this kind is doublecomplex, and its typecode is ‘D’.</p> <p>Complex kind objects have these addition attributes:</p> <p><code class="docutils literal notranslate"><span class="pre">floatkind</span></code> is the kind object of the corresponding float type.</p> </section> <section id="examples"> <h2><a class="toc-backref" href="#examples" role="doc-backlink">Examples</a></h2> <p>In module myprecision.py:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">kinds</span> <span class="n">tinyint</span> <span class="o">=</span> <span class="n">kinds</span><span class="o">.</span><span class="n">int_kind</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="n">single</span> <span class="o">=</span> <span class="n">kinds</span><span class="o">.</span><span class="n">float_kind</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span> <span class="mi">90</span><span class="p">)</span> <span class="n">double</span> <span class="o">=</span> <span class="n">kinds</span><span class="o">.</span><span class="n">float_kind</span><span class="p">(</span><span class="mi">15</span><span class="p">,</span> <span class="mi">300</span><span class="p">)</span> <span class="n">csingle</span> <span class="o">=</span> <span class="n">kinds</span><span class="o">.</span><span class="n">complex_kind</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span> <span class="mi">90</span><span class="p">)</span> </pre></div> </div> <p>In the rest of my code:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">myprecision</span><span class="w"> </span><span class="kn">import</span> <span class="n">tinyint</span><span class="p">,</span> <span class="n">single</span><span class="p">,</span> <span class="n">double</span><span class="p">,</span> <span class="n">csingle</span> <span class="n">n</span> <span class="o">=</span> <span class="n">tinyint</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="n">x</span> <span class="o">=</span> <span class="n">double</span><span class="p">(</span><span class="mf">1.e20</span><span class="p">)</span> <span class="n">z</span> <span class="o">=</span> <span class="mf">1.2</span> <span class="c1"># builtin float gets you the default float kind, properties unknown</span> <span class="n">w</span> <span class="o">=</span> <span class="n">x</span> <span class="o">*</span> <span class="nb">float</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="c1"># but in the following case we know w has kind &quot;double&quot;.</span> <span class="n">w</span> <span class="o">=</span> <span class="n">x</span> <span class="o">*</span> <span class="n">double</span><span class="p">(</span><span class="n">z</span><span class="p">)</span> <span class="n">u</span> <span class="o">=</span> <span class="n">csingle</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">z</span> <span class="o">*</span> <span class="mf">1.0</span><span class="n">j</span><span class="p">)</span> <span class="n">u2</span> <span class="o">=</span> <span class="n">csingle</span><span class="p">(</span><span class="n">x</span><span class="o">+</span><span class="n">z</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">)</span> </pre></div> </div> <p>Note how that entire code can then be changed to a higher precision by changing the arguments in myprecision.py.</p> <p>Comment: note that you aren’t promised that single != double; but you are promised that <code class="docutils literal notranslate"><span class="pre">double(1.e20)</span></code> will hold a number with 15 decimal digits of precision and a range up to <code class="docutils literal notranslate"><span class="pre">10**300</span></code> or that the <code class="docutils literal notranslate"><span class="pre">float_kind</span></code> call will fail.</p> </section> <section id="open-issues"> <h2><a class="toc-backref" href="#open-issues" role="doc-backlink">Open Issues</a></h2> <p>No open issues have been raised at this time.</p> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <p>This document has been placed in the public domain.</p> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0242.rst">https://github.com/python/peps/blob/main/peps/pep-0242.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0242.rst">2024-04-14 20:08:31 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#supported-kinds-of-ints-and-floats">Supported Kinds of Ints and Floats</a></li> <li><a class="reference internal" href="#kind-objects">Kind Objects</a></li> <li><a class="reference internal" href="#attributes-of-module-kinds">Attributes of Module kinds</a></li> <li><a class="reference internal" href="#complex-numbers">Complex Numbers</a></li> <li><a class="reference internal" href="#examples">Examples</a></li> <li><a class="reference internal" href="#open-issues">Open Issues</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> <br> <a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0242.rst">Page Source (GitHub)</a> </nav> </section> <script src="../_static/colour_scheme.js"></script> <script src="../_static/wrap_tables.js"></script> <script src="../_static/sticky_banner.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10