1360 lines
99 KiB
HTML
1360 lines
99 KiB
HTML
|
||
<!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 327 – Decimal Data Type | peps.python.org</title>
|
||
<link rel="shortcut icon" href="../_static/py.png">
|
||
<link rel="canonical" href="https://peps.python.org/pep-0327/">
|
||
<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 327 – Decimal Data Type | peps.python.org'>
|
||
<meta property="og:description" content="The idea is to have a Decimal data type, for every use where decimals are needed but binary floating point is too inexact.">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:url" content="https://peps.python.org/pep-0327/">
|
||
<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="The idea is to have a Decimal data type, for every use where decimals are needed but binary floating point is too inexact.">
|
||
<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> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </li>
|
||
<li>PEP 327</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 327 – Decimal Data Type</h1>
|
||
<dl class="rfc2822 field-list simple">
|
||
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
||
<dd class="field-odd">Facundo Batista <facundo at taniquetil.com.ar></dd>
|
||
<dt class="field-even">Status<span class="colon">:</span></dt>
|
||
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</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-Oct-2003</dd>
|
||
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
|
||
<dd class="field-odd">2.4</dd>
|
||
<dt class="field-even">Post-History<span class="colon">:</span></dt>
|
||
<dd class="field-even">30-Nov-2003, 02-Jan-2004, 29-Jan-2004</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="#motivation">Motivation</a><ul>
|
||
<li><a class="reference internal" href="#the-problem-with-binary-float">The problem with binary float</a></li>
|
||
<li><a class="reference internal" href="#why-floating-point">Why floating point?</a></li>
|
||
<li><a class="reference internal" href="#why-not-rational">Why not rational?</a></li>
|
||
<li><a class="reference internal" href="#so-what-do-we-have">So, what do we have?</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#general-decimal-arithmetic-specification">General Decimal Arithmetic Specification</a><ul>
|
||
<li><a class="reference internal" href="#the-arithmetic-model">The Arithmetic Model</a></li>
|
||
<li><a class="reference internal" href="#numbers">Numbers</a></li>
|
||
<li><a class="reference internal" href="#context">Context</a></li>
|
||
<li><a class="reference internal" href="#default-contexts">Default Contexts</a></li>
|
||
<li><a class="reference internal" href="#exceptional-conditions">Exceptional Conditions</a></li>
|
||
<li><a class="reference internal" href="#rounding-algorithms">Rounding Algorithms</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#rationale">Rationale</a><ul>
|
||
<li><a class="reference internal" href="#explicit-construction">Explicit construction</a><ul>
|
||
<li><a class="reference internal" href="#from-int-or-long">From int or long</a></li>
|
||
<li><a class="reference internal" href="#from-string">From string</a></li>
|
||
<li><a class="reference internal" href="#from-float">From float</a></li>
|
||
<li><a class="reference internal" href="#from-tuples">From tuples</a></li>
|
||
<li><a class="reference internal" href="#from-decimal">From Decimal</a></li>
|
||
<li><a class="reference internal" href="#syntax-for-all-cases">Syntax for All Cases</a></li>
|
||
<li><a class="reference internal" href="#creating-from-context">Creating from Context</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#implicit-construction">Implicit construction</a><ul>
|
||
<li><a class="reference internal" href="#id15">From int or long</a></li>
|
||
<li><a class="reference internal" href="#id16">From string</a></li>
|
||
<li><a class="reference internal" href="#id17">From float</a></li>
|
||
<li><a class="reference internal" href="#id18">From Decimal</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#use-of-context">Use of Context</a></li>
|
||
<li><a class="reference internal" href="#python-usability">Python Usability</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#documentation">Documentation</a><ul>
|
||
<li><a class="reference internal" href="#decimal-attributes">Decimal Attributes</a></li>
|
||
<li><a class="reference internal" href="#decimal-methods">Decimal Methods</a></li>
|
||
<li><a class="reference internal" href="#context-attributes">Context Attributes</a></li>
|
||
<li><a class="reference internal" href="#context-methods">Context Methods</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
|
||
<li><a class="reference internal" href="#references">References</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
</details></section>
|
||
<section id="abstract">
|
||
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
|
||
<p>The idea is to have a Decimal data type, for every use where decimals
|
||
are needed but binary floating point is too inexact.</p>
|
||
<p>The Decimal data type will support the Python standard functions and
|
||
operations, and must comply with the decimal arithmetic ANSI standard
|
||
X3.274-1996 <a class="footnote-reference brackets" href="#id19" id="id1">[1]</a>.</p>
|
||
<p>Decimal will be floating point (as opposed to fixed point) and will
|
||
have bounded precision (the precision is the upper limit on the
|
||
number of significant digits in a result). However, precision is
|
||
user-settable, and a notion of significant trailing zeroes is supported
|
||
so that fixed-point usage is also possible.</p>
|
||
<p>This work is based on code and test functions written by Eric Price,
|
||
Aahz and Tim Peters. Just before Python 2.4a1, the decimal.py
|
||
<a class="reference internal" href="#reference-implementation">reference implementation</a> was moved into the standard library; along
|
||
with the documentation and the test suite, this was the work of
|
||
Raymond Hettinger. Much of the explanation in this PEP is taken from
|
||
Cowlishaw’s work <a class="footnote-reference brackets" href="#id20" id="id2">[2]</a>, comp.lang.python and python-dev.</p>
|
||
</section>
|
||
<section id="motivation">
|
||
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
|
||
<p>Here I’ll expose the reasons of why I think a Decimal data type is
|
||
needed and why other numeric data types are not enough.</p>
|
||
<p>I wanted a Money data type, and after proposing a pre-PEP in
|
||
comp.lang.python, the community agreed to have a numeric data type
|
||
with the needed arithmetic behaviour, and then build Money over it:
|
||
all the considerations about quantity of digits after the decimal
|
||
point, rounding, etc., will be handled through Money. It is not the
|
||
purpose of this PEP to have a data type that can be used as Money
|
||
without further effort.</p>
|
||
<p>One of the biggest advantages of implementing a standard is that
|
||
someone already thought out all the creepy cases for you. And to a
|
||
standard GvR redirected me: Mike Cowlishaw’s General Decimal
|
||
Arithmetic specification <a class="footnote-reference brackets" href="#id20" id="id3">[2]</a>. This document defines a general
|
||
purpose decimal arithmetic. A correct implementation of this
|
||
specification will conform to the decimal arithmetic defined in
|
||
ANSI/IEEE standard 854-1987, except for some minor restrictions, and
|
||
will also provide unrounded decimal arithmetic and integer arithmetic
|
||
as proper subsets.</p>
|
||
<section id="the-problem-with-binary-float">
|
||
<h3><a class="toc-backref" href="#the-problem-with-binary-float" role="doc-backlink">The problem with binary float</a></h3>
|
||
<p>In decimal math, there are many numbers that can’t be represented with
|
||
a fixed number of decimal digits, e.g. 1/3 = 0.3333333333…….</p>
|
||
<p>In base 2 (the way that standard floating point is calculated), 1/2 =
|
||
0.1, 1/4 = 0.01, 1/8 = 0.001, etc. Decimal 0.2 equals 2/10 equals
|
||
1/5, resulting in the binary fractional number
|
||
0.001100110011001… As you can see, the problem is that some decimal
|
||
numbers can’t be represented exactly in binary, resulting in small
|
||
roundoff errors.</p>
|
||
<p>So we need a decimal data type that represents exactly decimal
|
||
numbers. Instead of a binary data type, we need a decimal one.</p>
|
||
</section>
|
||
<section id="why-floating-point">
|
||
<h3><a class="toc-backref" href="#why-floating-point" role="doc-backlink">Why floating point?</a></h3>
|
||
<p>So we go to decimal, but why <em>floating point</em>?</p>
|
||
<p>Floating point numbers use a fixed quantity of digits (precision) to
|
||
represent a number, working with an exponent when the number gets too
|
||
big or too small. For example, with a precision of 5:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="mi">1234</span> <span class="o">==></span> <span class="mf">1234e0</span>
|
||
<span class="mi">12345</span> <span class="o">==></span> <span class="mf">12345e0</span>
|
||
<span class="mi">123456</span> <span class="o">==></span> <span class="mf">12346e1</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>(note that in the last line the number got rounded to fit in five digits).</p>
|
||
<p>In contrast, we have the example of a <code class="docutils literal notranslate"><span class="pre">long</span></code> integer with infinite
|
||
precision, meaning that you can have the number as big as you want,
|
||
and you’ll never lose any information.</p>
|
||
<p>In a fixed point number, the position of the decimal point is fixed.
|
||
For a fixed point data type, check Tim Peter’s FixedPoint at
|
||
SourceForge <a class="footnote-reference brackets" href="#id22" id="id4">[4]</a>. I’ll go for floating point because it’s easier to
|
||
implement the arithmetic behaviour of the standard, and then you can
|
||
implement a fixed point data type over Decimal.</p>
|
||
<p>But why can’t we have a floating point number with infinite precision?
|
||
It’s not so easy, because of inexact divisions. E.g.: 1/3 =
|
||
0.3333333333333… ad infinitum. In this case you should store an
|
||
infinite amount of 3s, which takes too much memory, ;).</p>
|
||
<p>John Roth proposed to eliminate the division operator and force the
|
||
user to use an explicit method, just to avoid this kind of trouble.
|
||
This generated adverse reactions in comp.lang.python, as everybody
|
||
wants to have support for the <code class="docutils literal notranslate"><span class="pre">/</span></code> operator in a numeric data type.</p>
|
||
<p>With this exposed maybe you’re thinking “Hey! Can we just store the 1
|
||
and the 3 as numerator and denominator?”, which takes us to the next
|
||
point.</p>
|
||
</section>
|
||
<section id="why-not-rational">
|
||
<h3><a class="toc-backref" href="#why-not-rational" role="doc-backlink">Why not rational?</a></h3>
|
||
<p>Rational numbers are stored using two integer numbers, the numerator
|
||
and the denominator. This implies that the arithmetic operations
|
||
can’t be executed directly (e.g. to add two rational numbers you first
|
||
need to calculate the common denominator).</p>
|
||
<p>Quoting Alex Martelli:</p>
|
||
<blockquote>
|
||
<div>The performance implications of the fact that summing two
|
||
rationals (which take O(M) and O(N) space respectively) gives a
|
||
rational which takes O(M+N) memory space is just too troublesome.
|
||
There are excellent Rational implementations in both pure Python
|
||
and as extensions (e.g., gmpy), but they’ll always be a “niche
|
||
market” IMHO. Probably worth PEPping, not worth doing without
|
||
Decimal – which is the right way to represent sums of money, a
|
||
truly major use case in the real world.</div></blockquote>
|
||
<p>Anyway, if you’re interested in this data type, you maybe will want to
|
||
take a look at <a class="pep reference internal" href="../pep-0239/" title="PEP 239 – Adding a Rational Type to Python">PEP 239</a>: Adding a Rational Type to Python.</p>
|
||
</section>
|
||
<section id="so-what-do-we-have">
|
||
<h3><a class="toc-backref" href="#so-what-do-we-have" role="doc-backlink">So, what do we have?</a></h3>
|
||
<p>The result is a Decimal data type, with bounded precision and floating
|
||
point.</p>
|
||
<p>Will it be useful? I can’t say it better than Alex Martelli:</p>
|
||
<blockquote>
|
||
<div>Python (out of the box) doesn’t let you have binary floating point
|
||
numbers <em>with whatever precision you specify</em>: you’re limited to
|
||
what your hardware supplies. Decimal, be it used as a fixed or
|
||
floating point number, should suffer from no such limitation:
|
||
whatever bounded precision you may specify on number creation
|
||
(your memory permitting) should work just as well. Most of the
|
||
expense of programming simplicity can be hidden from application
|
||
programs and placed in a suitable decimal arithmetic type. As per
|
||
<a class="reference external" href="http://speleotrove.com/decimal/">http://speleotrove.com/decimal/</a>, <em>a single data type can be
|
||
used for integer, fixed-point, and floating-point decimal
|
||
arithmetic</em> – and for money arithmetic which doesn’t drive the
|
||
application programmer crazy.</div></blockquote>
|
||
<p>There are several uses for such a data type. As I said before, I will
|
||
use it as base for Money. In this case the bounded precision is not
|
||
an issue; quoting Tim Peters:</p>
|
||
<blockquote>
|
||
<div>A precision of 20 would be way more than enough to account for
|
||
total world economic output, down to the penny, since the
|
||
beginning of time.</div></blockquote>
|
||
</section>
|
||
</section>
|
||
<section id="general-decimal-arithmetic-specification">
|
||
<h2><a class="toc-backref" href="#general-decimal-arithmetic-specification" role="doc-backlink">General Decimal Arithmetic Specification</a></h2>
|
||
<p>Here I’ll include information and descriptions that are part of the
|
||
specification <a class="footnote-reference brackets" href="#id20" id="id5">[2]</a> (the structure of the number, the context, etc.).
|
||
All the requirements included in this section are not for discussion
|
||
(barring typos or other mistakes), as they are in the standard, and
|
||
the PEP is just for implementing the standard.</p>
|
||
<p>Because of copyright restrictions, I can not copy here explanations
|
||
taken from the specification, so I’ll try to explain it in my own
|
||
words. I firmly encourage you to read the original specification
|
||
document <a class="footnote-reference brackets" href="#id20" id="id6">[2]</a> for details or if you have any doubt.</p>
|
||
<section id="the-arithmetic-model">
|
||
<h3><a class="toc-backref" href="#the-arithmetic-model" role="doc-backlink">The Arithmetic Model</a></h3>
|
||
<p>The specification is based on a decimal arithmetic model, as defined
|
||
by the relevant standards: IEEE 854 <a class="footnote-reference brackets" href="#id21" id="id7">[3]</a>, ANSI X3-274 <a class="footnote-reference brackets" href="#id19" id="id8">[1]</a>, and the
|
||
proposed revision <a class="footnote-reference brackets" href="#id23" id="id9">[5]</a> of IEEE 754 <a class="footnote-reference brackets" href="#id24" id="id10">[6]</a>.</p>
|
||
<p>The model has three components:</p>
|
||
<ul class="simple">
|
||
<li>Numbers: just the values that the operation uses as input or output.</li>
|
||
<li>Operations: addition, multiplication, etc.</li>
|
||
<li>Context: a set of parameters and rules that the user can select and
|
||
which govern the results of operations (for example, the precision
|
||
to be used).</li>
|
||
</ul>
|
||
</section>
|
||
<section id="numbers">
|
||
<h3><a class="toc-backref" href="#numbers" role="doc-backlink">Numbers</a></h3>
|
||
<p>Numbers may be finite or special values. The former can be
|
||
represented exactly. The latter are infinites and undefined (such as
|
||
0/0).</p>
|
||
<p>Finite numbers are defined by three parameters:</p>
|
||
<ul class="simple">
|
||
<li>Sign: 0 (positive) or 1 (negative).</li>
|
||
<li>Coefficient: a non-negative integer.</li>
|
||
<li>Exponent: a signed integer, the power of ten of the coefficient
|
||
multiplier.</li>
|
||
</ul>
|
||
<p>The numerical value of a finite number is given by:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">**</span><span class="n">sign</span> <span class="o">*</span> <span class="n">coefficient</span> <span class="o">*</span> <span class="mi">10</span><span class="o">**</span><span class="n">exponent</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Special values are named as following:</p>
|
||
<ul class="simple">
|
||
<li>Infinity: a value which is infinitely large. Could be positive or
|
||
negative.</li>
|
||
<li>Quiet NaN (“qNaN”): represent undefined results (<em>Not a Number</em>).
|
||
Does not cause an Invalid operation condition. The sign in a NaN
|
||
has no meaning.</li>
|
||
<li>Signaling NaN (“sNaN”): also <em>Not a Number</em>, but will cause an
|
||
Invalid operation condition if used in any operation.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="context">
|
||
<h3><a class="toc-backref" href="#context" role="doc-backlink">Context</a></h3>
|
||
<p>The context is a set of parameters and rules that the user can select
|
||
and which govern the results of operations (for example, the precision
|
||
to be used).</p>
|
||
<p>The context gets that name because it surrounds the Decimal numbers,
|
||
with parts of context acting as input to, and output of, operations.
|
||
It’s up to the application to work with one or several contexts,
|
||
but definitely the idea is not to get a context per Decimal number.
|
||
For example, a typical use would be to set the context’s precision to
|
||
20 digits at the start of a program, and never explicitly use context
|
||
again.</p>
|
||
<p>These definitions don’t affect the internal storage of the Decimal
|
||
numbers, just the way that the arithmetic operations are performed.</p>
|
||
<p>The context is mainly defined by the following parameters (see
|
||
<a class="reference internal" href="#context-attributes">Context Attributes</a> for all context attributes):</p>
|
||
<ul class="simple">
|
||
<li>Precision: The maximum number of significant digits that can result
|
||
from an arithmetic operation (integer > 0). There is no maximum for
|
||
this value.</li>
|
||
<li>Rounding: The name of the algorithm to be used when rounding is
|
||
necessary, one of “round-down”, “round-half-up”, “round-half-even”,
|
||
“round-ceiling”, “round-floor”, “round-half-down”, and “round-up”.
|
||
See <a class="reference internal" href="#rounding-algorithms">Rounding Algorithms</a> below.</li>
|
||
<li>Flags and trap-enablers: <a class="reference internal" href="#exceptional-conditions">Exceptional conditions</a> are grouped into
|
||
signals, controllable individually, each consisting of a flag
|
||
(boolean, set when the signal occurs) and a trap-enabler (a boolean
|
||
that controls behavior). The signals are: “clamped”,
|
||
“division-by-zero”, “inexact”, “invalid-operation”, “overflow”,
|
||
“rounded”, “subnormal” and “underflow”.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="default-contexts">
|
||
<h3><a class="toc-backref" href="#default-contexts" role="doc-backlink">Default Contexts</a></h3>
|
||
<p>The specification defines two default contexts, which should be easily
|
||
selectable by the user.</p>
|
||
<p>Basic Default Context:</p>
|
||
<ul class="simple">
|
||
<li>flags: all set to 0</li>
|
||
<li>trap-enablers: inexact, rounded, and subnormal are set to 0; all
|
||
others are set to 1</li>
|
||
<li>precision: is set to 9</li>
|
||
<li>rounding: is set to round-half-up</li>
|
||
</ul>
|
||
<p>Extended Default Context:</p>
|
||
<ul class="simple">
|
||
<li>flags: all set to 0</li>
|
||
<li>trap-enablers: all set to 0</li>
|
||
<li>precision: is set to 9</li>
|
||
<li>rounding: is set to round-half-even</li>
|
||
</ul>
|
||
</section>
|
||
<section id="exceptional-conditions">
|
||
<h3><a class="toc-backref" href="#exceptional-conditions" role="doc-backlink">Exceptional Conditions</a></h3>
|
||
<p>The table below lists the exceptional conditions that may arise during
|
||
the arithmetic operations, the corresponding signal, and the defined
|
||
result. For details, see the specification <a class="footnote-reference brackets" href="#id20" id="id11">[2]</a>.</p>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head">Condition</th>
|
||
<th class="head">Signal</th>
|
||
<th class="head">Result</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td>Clamped</td>
|
||
<td>clamped</td>
|
||
<td>see spec <a class="footnote-reference brackets" href="#id20" id="id12">[2]</a></td>
|
||
</tr>
|
||
<tr class="row-odd"><td>Division by zero</td>
|
||
<td>division-by-zero</td>
|
||
<td>[sign,inf]</td>
|
||
</tr>
|
||
<tr class="row-even"><td>Inexact</td>
|
||
<td>inexact</td>
|
||
<td>unchanged</td>
|
||
</tr>
|
||
<tr class="row-odd"><td>Invalid operation</td>
|
||
<td>invalid-operation</td>
|
||
<td>[0,qNaN] (or [s,qNaN] or [s,qNaN,d]
|
||
when the cause is a signaling NaN)</td>
|
||
</tr>
|
||
<tr class="row-even"><td>Overflow</td>
|
||
<td>overflow</td>
|
||
<td>depends on the rounding mode</td>
|
||
</tr>
|
||
<tr class="row-odd"><td>Rounded</td>
|
||
<td>rounded</td>
|
||
<td>unchanged</td>
|
||
</tr>
|
||
<tr class="row-even"><td>Subnormal</td>
|
||
<td>subnormal</td>
|
||
<td>unchanged</td>
|
||
</tr>
|
||
<tr class="row-odd"><td>Underflow</td>
|
||
<td>underflow</td>
|
||
<td>see spec <a class="footnote-reference brackets" href="#id20" id="id13">[2]</a></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Note: when the standard talks about “Insufficient storage”, as long as
|
||
this is implementation-specific behaviour about not having enough
|
||
storage to keep the internals of the number, this implementation will
|
||
raise MemoryError.</p>
|
||
<p>Regarding Overflow and Underflow, there’s been a long discussion in
|
||
python-dev about artificial limits. The general consensus is to keep
|
||
the artificial limits only if there are important reasons to do that.
|
||
Tim Peters gives us three:</p>
|
||
<blockquote>
|
||
<div>…eliminating bounds on exponents effectively means overflow
|
||
(and underflow) can never happen. But overflow <em>is</em> a valuable
|
||
safety net in real life fp use, like a canary in a coal mine,
|
||
giving danger signs early when a program goes insane.<p>Virtually all implementations of 854 use (and as IBM’s standard
|
||
even suggests) “forbidden” exponent values to encode non-finite
|
||
numbers (infinities and NaNs). A bounded exponent can do this at
|
||
virtually no extra storage cost. If the exponent is unbounded,
|
||
then additional bits have to be used instead. This cost remains
|
||
hidden until more time- and space- efficient implementations are
|
||
attempted.</p>
|
||
<p>Big as it is, the IBM standard is a tiny start at supplying a
|
||
complete numeric facility. Having no bound on exponent size will
|
||
enormously complicate the implementations of, e.g., decimal sin()
|
||
and cos() (there’s then no a priori limit on how many digits of
|
||
pi effectively need to be known in order to perform argument
|
||
reduction).</p>
|
||
</div></blockquote>
|
||
<p>Edward Loper give us an example of when the limits are to be crossed:
|
||
probabilities.</p>
|
||
<p>That said, Robert Brewer and Andrew Lentvorski want the limits to be
|
||
easily modifiable by the users. Actually, this is quite possible:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d1</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s2">"1e999999999"</span><span class="p">)</span> <span class="c1"># at the exponent limit</span>
|
||
<span class="gp">>>> </span><span class="n">d1</span>
|
||
<span class="go">Decimal("1E+999999999")</span>
|
||
<span class="gp">>>> </span><span class="n">d1</span> <span class="o">*</span> <span class="mi">10</span> <span class="c1"># exceed the limit, got infinity</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
File <span class="nb">"<pyshell#3>"</span>, line <span class="m">1</span>, in <span class="n">?</span>
|
||
<span class="w"> </span><span class="n">d1</span> <span class="o">*</span> <span class="mi">10</span>
|
||
<span class="w"> </span><span class="c">...</span>
|
||
<span class="w"> </span><span class="c">...</span>
|
||
<span class="gr">Overflow</span>: <span class="n">above Emax</span>
|
||
<span class="gp">>>> </span><span class="n">getcontext</span><span class="p">()</span><span class="o">.</span><span class="n">Emax</span> <span class="o">=</span> <span class="mi">1000000000</span> <span class="c1"># increase the limit</span>
|
||
<span class="gp">>>> </span><span class="n">d1</span> <span class="o">*</span> <span class="mi">10</span> <span class="c1"># does not exceed any more</span>
|
||
<span class="go">Decimal("1.0E+1000000000")</span>
|
||
<span class="gp">>>> </span><span class="n">d1</span> <span class="o">*</span> <span class="mi">100</span> <span class="c1"># exceed again</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
File <span class="nb">"<pyshell#3>"</span>, line <span class="m">1</span>, in <span class="n">?</span>
|
||
<span class="w"> </span><span class="n">d1</span> <span class="o">*</span> <span class="mi">100</span>
|
||
<span class="w"> </span><span class="c">...</span>
|
||
<span class="w"> </span><span class="c">...</span>
|
||
<span class="gr">Overflow</span>: <span class="n">above Emax</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="rounding-algorithms">
|
||
<h3><a class="toc-backref" href="#rounding-algorithms" role="doc-backlink">Rounding Algorithms</a></h3>
|
||
<p><code class="docutils literal notranslate"><span class="pre">round-down</span></code>: The discarded digits are ignored; the result is
|
||
unchanged (round toward 0, truncate):</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">1.123</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="mf">1.128</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="mf">1.125</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="mf">1.135</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">round-half-up</span></code>: If the discarded digits represent greater than or
|
||
equal to half (0.5) then the result should be incremented by 1;
|
||
otherwise the discarded digits are ignored:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">1.123</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="mf">1.128</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
<span class="mf">1.125</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
<span class="mf">1.135</span> <span class="o">--></span> <span class="mf">1.14</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">round-half-even</span></code>: If the discarded digits represent greater than
|
||
half (0.5) then the result coefficient is incremented by 1; if they
|
||
represent less than half, then the result is not adjusted; otherwise
|
||
the result is unaltered if its rightmost digit is even, or incremented
|
||
by 1 if its rightmost digit is odd (to make an even digit):</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">1.123</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="mf">1.128</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
<span class="mf">1.125</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="mf">1.135</span> <span class="o">--></span> <span class="mf">1.14</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">round-ceiling</span></code>: If all of the discarded digits are zero or if the
|
||
sign is negative the result is unchanged; otherwise, the result is
|
||
incremented by 1 (round toward positive infinity):</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="mf">1.123</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
<span class="mf">1.128</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
<span class="o">-</span><span class="mf">1.123</span> <span class="o">--></span> <span class="o">-</span><span class="mf">1.12</span>
|
||
<span class="o">-</span><span class="mf">1.128</span> <span class="o">--></span> <span class="o">-</span><span class="mf">1.12</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">round-floor</span></code>: If all of the discarded digits are zero or if the
|
||
sign is positive the result is unchanged; otherwise, the absolute
|
||
value of the result is incremented by 1 (round toward negative
|
||
infinity):</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="mf">1.123</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="mf">1.128</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="o">-</span><span class="mf">1.123</span> <span class="o">--></span> <span class="o">-</span><span class="mf">1.13</span>
|
||
<span class="o">-</span><span class="mf">1.128</span> <span class="o">--></span> <span class="o">-</span><span class="mf">1.13</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">round-half-down</span></code>: If the discarded digits represent greater than
|
||
half (0.5) then the result is incremented by 1; otherwise the
|
||
discarded digits are ignored:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">1.123</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="mf">1.128</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
<span class="mf">1.125</span> <span class="o">--></span> <span class="mf">1.12</span>
|
||
<span class="mf">1.135</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">round-up</span></code>: If all of the discarded digits are zero the result is
|
||
unchanged, otherwise the result is incremented by 1 (round away from
|
||
0):</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">1.123</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
<span class="mf">1.128</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
<span class="mf">1.125</span> <span class="o">--></span> <span class="mf">1.13</span>
|
||
<span class="mf">1.135</span> <span class="o">--></span> <span class="mf">1.14</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="rationale">
|
||
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
|
||
<p>I must separate the requirements in two sections. The first is to
|
||
comply with the ANSI standard. All the requirements for this are
|
||
specified in the Mike Cowlishaw’s work <a class="footnote-reference brackets" href="#id20" id="id14">[2]</a>. He also provided a
|
||
<strong>very large</strong> suite of test cases.</p>
|
||
<p>The second section of requirements (standard Python functions support,
|
||
usability, etc.) is detailed from here, where I’ll include all the
|
||
decisions made and why, and all the subjects still being discussed.</p>
|
||
<section id="explicit-construction">
|
||
<h3><a class="toc-backref" href="#explicit-construction" role="doc-backlink">Explicit construction</a></h3>
|
||
<p>The explicit construction does not get affected by the context (there
|
||
is no rounding, no limits by the precision, etc.), because the context
|
||
affects just operations’ results. The only exception to this is when
|
||
you’re <a class="reference internal" href="#creating-from-context">Creating from Context</a>.</p>
|
||
<section id="from-int-or-long">
|
||
<h4><a class="toc-backref" href="#from-int-or-long" role="doc-backlink">From int or long</a></h4>
|
||
<p>There’s no loss and no need to specify any other information:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Decimal</span><span class="p">(</span><span class="mi">35</span><span class="p">)</span>
|
||
<span class="n">Decimal</span><span class="p">(</span><span class="o">-</span><span class="mi">124</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="from-string">
|
||
<h4><a class="toc-backref" href="#from-string" role="doc-backlink">From string</a></h4>
|
||
<p>Strings containing Python decimal integer literals and Python float
|
||
literals will be supported. In this transformation there is no loss
|
||
of information, as the string is directly converted to Decimal (there
|
||
is not an intermediate conversion through float):</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Decimal</span><span class="p">(</span><span class="s2">"-12"</span><span class="p">)</span>
|
||
<span class="n">Decimal</span><span class="p">(</span><span class="s2">"23.2e-7"</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Also, you can construct in this way all special values (Infinity and
|
||
Not a Number):</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Decimal</span><span class="p">(</span><span class="s2">"Inf"</span><span class="p">)</span>
|
||
<span class="n">Decimal</span><span class="p">(</span><span class="s2">"NaN"</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="from-float">
|
||
<h4><a class="toc-backref" href="#from-float" role="doc-backlink">From float</a></h4>
|
||
<p>The initial discussion on this item was what should
|
||
happen when passing floating point to the constructor:</p>
|
||
<ol class="arabic simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">Decimal(1.1)</span> <span class="pre">==</span> <span class="pre">Decimal('1.1')</span></code></li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">Decimal(1.1)</span> <span class="pre">==</span>
|
||
<span class="pre">Decimal('110000000000000008881784197001252...e-51')</span></code></li>
|
||
<li>an exception is raised</li>
|
||
</ol>
|
||
<p>Several people alleged that (1) is the better option here, because
|
||
it’s what you expect when writing <code class="docutils literal notranslate"><span class="pre">Decimal(1.1)</span></code>. And quoting John
|
||
Roth, it’s easy to implement:</p>
|
||
<blockquote>
|
||
<div>It’s not at all difficult to find where the actual number ends and
|
||
where the fuzz begins. You can do it visually, and the algorithms
|
||
to do it are quite well known.</div></blockquote>
|
||
<p>But If I <em>really</em> want my number to be
|
||
<code class="docutils literal notranslate"><span class="pre">Decimal('110000000000000008881784197001252...e-51')</span></code>, why can’t I
|
||
write <code class="docutils literal notranslate"><span class="pre">Decimal(1.1)</span></code>? Why should I expect Decimal to be “rounding”
|
||
it? Remember that <code class="docutils literal notranslate"><span class="pre">1.1</span></code> <em>is</em> binary floating point, so I can
|
||
predict the result. It’s not intuitive to a beginner, but that’s the
|
||
way it is.</p>
|
||
<p>Anyway, Paul Moore showed that (1) can’t work, because:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="n">says</span> <span class="n">D</span><span class="p">(</span><span class="mf">1.1</span><span class="p">)</span> <span class="o">==</span> <span class="n">D</span><span class="p">(</span><span class="s1">'1.1'</span><span class="p">)</span>
|
||
<span class="n">but</span> <span class="mf">1.1</span> <span class="o">==</span> <span class="mf">1.1000000000000001</span>
|
||
<span class="n">so</span> <span class="n">D</span><span class="p">(</span><span class="mf">1.1</span><span class="p">)</span> <span class="o">==</span> <span class="n">D</span><span class="p">(</span><span class="mf">1.1000000000000001</span><span class="p">)</span>
|
||
<span class="n">together</span><span class="p">:</span> <span class="n">D</span><span class="p">(</span><span class="mf">1.1000000000000001</span><span class="p">)</span> <span class="o">==</span> <span class="n">D</span><span class="p">(</span><span class="s1">'1.1'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>which is wrong, because if I write <code class="docutils literal notranslate"><span class="pre">Decimal('1.1')</span></code> it is exact, not
|
||
<code class="docutils literal notranslate"><span class="pre">D(1.1000000000000001)</span></code>. He also proposed to have an explicit
|
||
conversion to float. bokr says you need to put the precision in the
|
||
constructor and mwilson agreed:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span> <span class="p">(</span><span class="mf">1.1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="c1"># take float value to 1 decimal place</span>
|
||
<span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span> <span class="p">(</span><span class="mf">1.1</span><span class="p">)</span> <span class="c1"># gets `places` from pre-set context</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>But Alex Martelli says that:</p>
|
||
<blockquote>
|
||
<div>Constructing with some specified precision would be fine. Thus,
|
||
I think “construction from float with some default precision” runs
|
||
a substantial risk of tricking naive users.</div></blockquote>
|
||
<p>So, the accepted solution through c.l.p is that you can not call Decimal
|
||
with a float. Instead you must use a method: Decimal.from_float(). The
|
||
syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Decimal</span><span class="o">.</span><span class="n">from_float</span><span class="p">(</span><span class="n">floatNumber</span><span class="p">,</span> <span class="p">[</span><span class="n">decimal_places</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>where <code class="docutils literal notranslate"><span class="pre">floatNumber</span></code> is the float number origin of the construction
|
||
and <code class="docutils literal notranslate"><span class="pre">decimal_places</span></code> are the number of digits after the decimal
|
||
point where you apply a round-half-up rounding, if any. In this way
|
||
you can do, for example:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Decimal</span><span class="o">.</span><span class="n">from_float</span><span class="p">(</span><span class="mf">1.1</span><span class="p">,</span> <span class="mi">2</span><span class="p">):</span> <span class="n">The</span> <span class="n">same</span> <span class="k">as</span> <span class="n">doing</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'1.1'</span><span class="p">)</span><span class="o">.</span>
|
||
<span class="n">Decimal</span><span class="o">.</span><span class="n">from_float</span><span class="p">(</span><span class="mf">1.1</span><span class="p">,</span> <span class="mi">16</span><span class="p">):</span> <span class="n">The</span> <span class="n">same</span> <span class="k">as</span> <span class="n">doing</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'1.1000000000000001'</span><span class="p">)</span><span class="o">.</span>
|
||
<span class="n">Decimal</span><span class="o">.</span><span class="n">from_float</span><span class="p">(</span><span class="mf">1.1</span><span class="p">):</span> <span class="n">The</span> <span class="n">same</span> <span class="k">as</span> <span class="n">doing</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'1100000000000000088817841970012523233890533447265625e-51'</span><span class="p">)</span><span class="o">.</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Based on later discussions, it was decided to omit from_float() from the
|
||
API for Py2.4. Several ideas contributed to the thought process:</p>
|
||
<ul>
|
||
<li>Interactions between decimal and binary floating point force the user to
|
||
deal with tricky issues of representation and round-off. Avoidance of those
|
||
issues is a primary reason for having the module in the first place.</li>
|
||
<li>The first release of the module should focus on that which is safe, minimal,
|
||
and essential.</li>
|
||
<li>While theoretically nice, real world use cases for interactions between floats
|
||
and decimals are lacking. Java included float/decimal conversions to handle
|
||
an obscure case where calculations are best performed in decimal even though
|
||
a legacy data structure requires the inputs and outputs to be stored in
|
||
binary floating point.</li>
|
||
<li>If the need arises, users can use string representations as an intermediate
|
||
type. The advantage of this approach is that it makes explicit the
|
||
assumptions about precision and representation (no wondering what is going
|
||
on under the hood).</li>
|
||
<li>The Java docs for BigDecimal(double val) reflected their experiences with
|
||
the constructor:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">The</span> <span class="n">results</span> <span class="n">of</span> <span class="n">this</span> <span class="n">constructor</span> <span class="n">can</span> <span class="n">be</span> <span class="n">somewhat</span>
|
||
<span class="n">unpredictable</span> <span class="ow">and</span> <span class="n">its</span> <span class="n">use</span> <span class="ow">is</span> <span class="n">generally</span> <span class="ow">not</span> <span class="n">recommended</span><span class="o">.</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section id="from-tuples">
|
||
<h4><a class="toc-backref" href="#from-tuples" role="doc-backlink">From tuples</a></h4>
|
||
<p>Aahz suggested to construct from tuples: it’s easier
|
||
to implement <code class="docutils literal notranslate"><span class="pre">eval()</span></code>’s round trip and “someone who has numeric
|
||
values representing a Decimal does not need to convert them to a
|
||
string.”</p>
|
||
<p>The structure will be a tuple of three elements: sign, number and
|
||
exponent. The sign is 1 or 0, the number is a tuple of decimal digits
|
||
and the exponent is a signed int or long:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Decimal</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span> <span class="o">-</span><span class="mi">2</span><span class="p">))</span> <span class="c1"># for -32.25</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Of course, you can construct in this way all special values:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Decimal</span><span class="p">(</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,),</span> <span class="s1">'F'</span><span class="p">)</span> <span class="p">)</span> <span class="c1"># for Infinity</span>
|
||
<span class="n">Decimal</span><span class="p">(</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,),</span> <span class="s1">'n'</span><span class="p">)</span> <span class="p">)</span> <span class="c1"># for Not a Number</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="from-decimal">
|
||
<h4><a class="toc-backref" href="#from-decimal" role="doc-backlink">From Decimal</a></h4>
|
||
<p>No mystery here, just a copy.</p>
|
||
</section>
|
||
<section id="syntax-for-all-cases">
|
||
<h4><a class="toc-backref" href="#syntax-for-all-cases" role="doc-backlink">Syntax for All Cases</a></h4>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Decimal</span><span class="p">(</span><span class="n">value1</span><span class="p">)</span>
|
||
<span class="n">Decimal</span><span class="o">.</span><span class="n">from_float</span><span class="p">(</span><span class="n">value2</span><span class="p">,</span> <span class="p">[</span><span class="n">decimal_places</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>where <code class="docutils literal notranslate"><span class="pre">value1</span></code> can be int, long, string, 3-tuple or Decimal,
|
||
<code class="docutils literal notranslate"><span class="pre">value2</span></code> can only be float, and <code class="docutils literal notranslate"><span class="pre">decimal_places</span></code> is an optional
|
||
non negative int.</p>
|
||
</section>
|
||
<section id="creating-from-context">
|
||
<h4><a class="toc-backref" href="#creating-from-context" role="doc-backlink">Creating from Context</a></h4>
|
||
<p>This item arose in python-dev from two sources in parallel. Ka-Ping
|
||
Yee proposes to pass the context as an argument at instance creation
|
||
(he wants the context he passes to be used only in creation time: “It
|
||
would not be persistent”). Tony Meyer asks from_string to honor the
|
||
context if it receives a parameter “honour_context” with a True value.
|
||
(I don’t like it, because the doc specifies that the context be
|
||
honored and I don’t want the method to comply with the specification
|
||
regarding the value of an argument.)</p>
|
||
<p>Tim Peters gives us a reason to have a creation that uses context:</p>
|
||
<blockquote>
|
||
<div>In general number-crunching, literals may be given to high
|
||
precision, but that precision isn’t free and <em>usually</em> isn’t
|
||
needed</div></blockquote>
|
||
<p>Casey Duncan wants to use another method, not a bool arg:</p>
|
||
<blockquote>
|
||
<div>I find boolean arguments a general anti-pattern, especially given
|
||
we have class methods. Why not use an alternate constructor like
|
||
Decimal.rounded_to_context(“3.14159265”).</div></blockquote>
|
||
<p>In the process of deciding the syntax of that, Tim came up with a
|
||
better idea: he proposes not to have a method in Decimal to create
|
||
with a different context, but having instead a method in Context to
|
||
create a Decimal instance. Basically, instead of:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="o">.</span><span class="n">using_context</span><span class="p">(</span><span class="n">number</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>it will be:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">context</span><span class="o">.</span><span class="n">create_decimal</span><span class="p">(</span><span class="n">number</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>From Tim:</p>
|
||
<blockquote>
|
||
<div>While all operations in the spec except for the two to-string
|
||
operations use context, no operations in the spec support an
|
||
optional local context. That the Decimal() constructor ignores
|
||
context by default is an extension to the spec. We must supply a
|
||
context-honoring from-string operation to meet the spec. I
|
||
recommend against any concept of “local context” in any operation
|
||
– it complicates the model and isn’t necessary.</div></blockquote>
|
||
<p>So, we decided to use a context method to create a Decimal that will
|
||
use (only to be created) that context in particular (for further
|
||
operations it will use the context of the thread). But, a method with
|
||
what name?</p>
|
||
<p>Tim Peters proposes three methods to create from diverse sources
|
||
(from_string, from_int, from_float). I proposed to use one method,
|
||
<code class="docutils literal notranslate"><span class="pre">create_decimal()</span></code>, without caring about the data type. Michael
|
||
Chermside: “The name just fits my brain. The fact that it uses the
|
||
context is obvious from the fact that it’s Context method”.</p>
|
||
<p>The community agreed with that. I think that it’s OK because a newbie
|
||
will not be using the creation method from Context (the separate
|
||
method in Decimal to construct from float is just to prevent newbies
|
||
from encountering binary floating point issues).</p>
|
||
<p>So, in short, if you want to create a Decimal instance using a
|
||
particular context (that will be used just at creation time and not
|
||
any further), you’ll have to use a method of that context:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># n is any datatype accepted in Decimal(n) plus float</span>
|
||
<span class="n">mycontext</span><span class="o">.</span><span class="n">create_decimal</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Example:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="c1"># create a standard decimal instance</span>
|
||
<span class="gp">>>> </span><span class="n">Decimal</span><span class="p">(</span><span class="s2">"11.2233445566778899"</span><span class="p">)</span>
|
||
<span class="go">Decimal("11.2233445566778899")</span>
|
||
<span class="gp">>>></span>
|
||
<span class="gp">>>> </span><span class="c1"># create a decimal instance using the thread context</span>
|
||
<span class="gp">>>> </span><span class="n">thread_context</span> <span class="o">=</span> <span class="n">getcontext</span><span class="p">()</span>
|
||
<span class="gp">>>> </span><span class="n">thread_context</span><span class="o">.</span><span class="n">prec</span>
|
||
<span class="go">28</span>
|
||
<span class="gp">>>> </span><span class="n">thread_context</span><span class="o">.</span><span class="n">create_decimal</span><span class="p">(</span><span class="s2">"11.2233445566778899"</span><span class="p">)</span>
|
||
<span class="go">Decimal("11.2233445566778899")</span>
|
||
<span class="gp">>>></span>
|
||
<span class="gp">>>> </span><span class="c1"># create a decimal instance using other context</span>
|
||
<span class="gp">>>> </span><span class="n">other_context</span> <span class="o">=</span> <span class="n">thread_context</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
|
||
<span class="gp">>>> </span><span class="n">other_context</span><span class="o">.</span><span class="n">prec</span> <span class="o">=</span> <span class="mi">4</span>
|
||
<span class="gp">>>> </span><span class="n">other_context</span><span class="o">.</span><span class="n">create_decimal</span><span class="p">(</span><span class="s2">"11.2233445566778899"</span><span class="p">)</span>
|
||
<span class="go">Decimal("11.22")</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="implicit-construction">
|
||
<h3><a class="toc-backref" href="#implicit-construction" role="doc-backlink">Implicit construction</a></h3>
|
||
<p>As the implicit construction is the consequence of an operation, it
|
||
will be affected by the context as is detailed in each point.</p>
|
||
<p>John Roth suggested that “The other type should be handled in the same
|
||
way the decimal() constructor would handle it”. But Alex Martelli
|
||
thinks that</p>
|
||
<blockquote>
|
||
<div>this total breach with Python tradition would be a terrible
|
||
mistake. 23+”43” is NOT handled in the same way as 23+int(“45”),
|
||
and a VERY good thing that is too. It’s a completely different
|
||
thing for a user to EXPLICITLY indicate they want construction
|
||
(conversion) and to just happen to sum two objects one of which by
|
||
mistake could be a string.</div></blockquote>
|
||
<p>So, here I define the behaviour again for each data type.</p>
|
||
<section id="id15">
|
||
<h4><a class="toc-backref" href="#id15" role="doc-backlink">From int or long</a></h4>
|
||
<p>An int or long is a treated like a Decimal explicitly constructed from
|
||
Decimal(str(x)) in the current context (meaning that the to-string rules
|
||
for rounding are applied and the appropriate flags are set). This
|
||
guarantees that expressions like <code class="docutils literal notranslate"><span class="pre">Decimal('1234567')</span> <span class="pre">+</span> <span class="pre">13579</span></code> match
|
||
the mental model of <code class="docutils literal notranslate"><span class="pre">Decimal('1234567')</span> <span class="pre">+</span> <span class="pre">Decimal('13579')</span></code>. That
|
||
model works because all integers are representable as strings without
|
||
representation error.</p>
|
||
</section>
|
||
<section id="id16">
|
||
<h4><a class="toc-backref" href="#id16" role="doc-backlink">From string</a></h4>
|
||
<p>Everybody agrees to raise an exception here.</p>
|
||
</section>
|
||
<section id="id17">
|
||
<h4><a class="toc-backref" href="#id17" role="doc-backlink">From float</a></h4>
|
||
<p>Aahz is strongly opposed to interact with float, suggesting an
|
||
explicit conversion:</p>
|
||
<blockquote>
|
||
<div>The problem is that Decimal is capable of greater precision,
|
||
accuracy, and range than float.</div></blockquote>
|
||
<p>The example of the valid python expression, <code class="docutils literal notranslate"><span class="pre">35</span> <span class="pre">+</span> <span class="pre">1.1</span></code>, seems to suggest
|
||
that <code class="docutils literal notranslate"><span class="pre">Decimal(35)</span> <span class="pre">+</span> <span class="pre">1.1</span></code> should also be valid. However, a closer look
|
||
shows that it only demonstrates the feasibility of integer to floating
|
||
point conversions. Hence, the correct analog for decimal floating point
|
||
is <code class="docutils literal notranslate"><span class="pre">35</span> <span class="pre">+</span> <span class="pre">Decimal(1.1)</span></code>. Both coercions, int-to-float and int-to-Decimal,
|
||
can be done without incurring representation error.</p>
|
||
<p>The question of how to coerce between binary and decimal floating point
|
||
is more complex. I proposed allowing the interaction with float,
|
||
making an exact conversion and raising ValueError if exceeds the
|
||
precision in the current context (this is maybe too tricky, because
|
||
for example with a precision of 9, <code class="docutils literal notranslate"><span class="pre">Decimal(35)</span> <span class="pre">+</span> <span class="pre">1.2</span></code> is OK but
|
||
<code class="docutils literal notranslate"><span class="pre">Decimal(35)</span> <span class="pre">+</span> <span class="pre">1.1</span></code> raises an error).</p>
|
||
<p>This resulted to be too tricky. So tricky, that c.l.p agreed to raise
|
||
TypeError in this case: you could not mix Decimal and float.</p>
|
||
</section>
|
||
<section id="id18">
|
||
<h4><a class="toc-backref" href="#id18" role="doc-backlink">From Decimal</a></h4>
|
||
<p>There isn’t any issue here.</p>
|
||
</section>
|
||
</section>
|
||
<section id="use-of-context">
|
||
<h3><a class="toc-backref" href="#use-of-context" role="doc-backlink">Use of Context</a></h3>
|
||
<p>In the last pre-PEP I said that “The Context must be omnipresent,
|
||
meaning that changes to it affects all the current and future Decimal
|
||
instances”. I was wrong. In response, John Roth said:</p>
|
||
<blockquote>
|
||
<div>The context should be selectable for the particular usage. That
|
||
is, it should be possible to have several different contexts in
|
||
play at one time in an application.</div></blockquote>
|
||
<p>In comp.lang.python, Aahz explained that the idea is to have a
|
||
“context per thread”. So, all the instances of a thread belongs to a
|
||
context, and you can change a context in thread A (and the behaviour
|
||
of the instances of that thread) without changing nothing in thread B.</p>
|
||
<p>Also, and again correcting me, he said:</p>
|
||
<blockquote>
|
||
<div>(the) Context applies only to operations, not to Decimal
|
||
instances; changing the Context does not affect existing instances
|
||
if there are no operations on them.</div></blockquote>
|
||
<p>Arguing about special cases when there’s need to perform operations
|
||
with other rules that those of the current context, Tim Peters said
|
||
that the context will have the operations as methods. This way, the
|
||
user “can create whatever private context object(s) it needs, and
|
||
spell arithmetic as explicit method calls on its private context
|
||
object(s), so that the default thread context object is neither
|
||
consulted nor modified”.</p>
|
||
</section>
|
||
<section id="python-usability">
|
||
<h3><a class="toc-backref" href="#python-usability" role="doc-backlink">Python Usability</a></h3>
|
||
<ul>
|
||
<li>Decimal should support the basic arithmetic (<code class="docutils literal notranslate"><span class="pre">+,</span> <span class="pre">-,</span> <span class="pre">*,</span> <span class="pre">/,</span> <span class="pre">//,</span> <span class="pre">**,</span>
|
||
<span class="pre">%,</span> <span class="pre">divmod</span></code>) and comparison (<code class="docutils literal notranslate"><span class="pre">==,</span> <span class="pre">!=,</span> <span class="pre"><,</span> <span class="pre">>,</span> <span class="pre"><=,</span> <span class="pre">>=,</span> <span class="pre">cmp</span></code>)
|
||
operators in the following cases (check <a class="reference internal" href="#implicit-construction">Implicit Construction</a> to
|
||
see what types could OtherType be, and what happens in each case):<ul class="simple">
|
||
<li>Decimal op Decimal</li>
|
||
<li>Decimal op otherType</li>
|
||
<li>otherType op Decimal</li>
|
||
<li>Decimal op= Decimal</li>
|
||
<li>Decimal op= otherType</li>
|
||
</ul>
|
||
</li>
|
||
<li>Decimal should support unary operators (<code class="docutils literal notranslate"><span class="pre">-,</span> <span class="pre">+,</span> <span class="pre">abs</span></code>).</li>
|
||
<li>repr() should round trip, meaning that:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">m</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
|
||
<span class="n">m</span> <span class="o">==</span> <span class="nb">eval</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="n">m</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>Decimal should be immutable.</li>
|
||
<li>Decimal should support the built-in methods:<ul class="simple">
|
||
<li>min, max</li>
|
||
<li>float, int, long</li>
|
||
<li>str, repr</li>
|
||
<li>hash</li>
|
||
<li>bool (0 is false, otherwise true)</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p>There’s been some discussion in python-dev about the behaviour of
|
||
<code class="docutils literal notranslate"><span class="pre">hash()</span></code>. The community agrees that if the values are the same, the
|
||
hashes of those values should also be the same. So, while Decimal(25)
|
||
== 25 is True, hash(Decimal(25)) should be equal to hash(25).</p>
|
||
<p>The detail is that you can NOT compare Decimal to floats or strings,
|
||
so we should not worry about them giving the same hashes. In short:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">hash</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">==</span> <span class="nb">hash</span><span class="p">(</span><span class="n">Decimal</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> <span class="c1"># Only if n is int, long, or Decimal</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Regarding str() and repr() behaviour, Ka-Ping Yee proposes that repr()
|
||
have the same behaviour as str() and Tim Peters proposes that str()
|
||
behave like the to-scientific-string operation from the Spec.</p>
|
||
<p>This is possible, because (from Aahz): “The string form already
|
||
contains all the necessary information to reconstruct a Decimal
|
||
object”.</p>
|
||
<p>And it also complies with the Spec; Tim Peters:</p>
|
||
<blockquote>
|
||
<div>There’s no requirement to have a method <em>named</em> “to_sci_string”,
|
||
the only requirement is that <em>some</em> way to spell to-sci-string’s
|
||
functionality be supplied. The meaning of to-sci-string is
|
||
precisely specified by the standard, and is a good choice for both
|
||
str(Decimal) and repr(Decimal).</div></blockquote>
|
||
</section>
|
||
</section>
|
||
<section id="documentation">
|
||
<h2><a class="toc-backref" href="#documentation" role="doc-backlink">Documentation</a></h2>
|
||
<p>This section explains all the public methods and attributes of Decimal
|
||
and Context.</p>
|
||
<section id="decimal-attributes">
|
||
<h3><a class="toc-backref" href="#decimal-attributes" role="doc-backlink">Decimal Attributes</a></h3>
|
||
<p>Decimal has no public attributes. The internal information is stored
|
||
in slots and should not be accessed by end users.</p>
|
||
</section>
|
||
<section id="decimal-methods">
|
||
<h3><a class="toc-backref" href="#decimal-methods" role="doc-backlink">Decimal Methods</a></h3>
|
||
<p>Following are the conversion and arithmetic operations defined in the
|
||
Spec, and how that functionality can be achieved with the actual
|
||
implementation.</p>
|
||
<ul>
|
||
<li>to-scientific-string: Use builtin function <code class="docutils literal notranslate"><span class="pre">str()</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'123456789012.345'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="nb">str</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
|
||
<span class="go">'1.23456789E+11'</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>to-engineering-string: Use method <code class="docutils literal notranslate"><span class="pre">to_eng_string()</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'123456789012.345'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">to_eng_string</span><span class="p">()</span>
|
||
<span class="go">'123.456789E+9'</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>to-number: Use Context method <code class="docutils literal notranslate"><span class="pre">create_decimal()</span></code>. The standard
|
||
constructor or <code class="docutils literal notranslate"><span class="pre">from_float()</span></code> constructor cannot be used because
|
||
these do not use the context (as is specified in the Spec for this
|
||
conversion).</li>
|
||
<li>abs: Use builtin function <code class="docutils literal notranslate"><span class="pre">abs()</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'-15.67'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="nb">abs</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
|
||
<span class="go">Decimal('15.67')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>add: Use operator <code class="docutils literal notranslate"><span class="pre">+</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'15.6'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">+</span> <span class="mi">8</span>
|
||
<span class="go">Decimal('23.6')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>subtract: Use operator <code class="docutils literal notranslate"><span class="pre">-</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'15.6'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">-</span> <span class="mi">8</span>
|
||
<span class="go">Decimal('7.6')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>compare: Use method <code class="docutils literal notranslate"><span class="pre">compare()</span></code>. This method (and not the
|
||
built-in function cmp()) should only be used when dealing with
|
||
<em>special values</em>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'-15.67'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">nan</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'NaN'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">compare</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span>
|
||
<span class="go">'-1'</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">compare</span><span class="p">(</span><span class="n">nan</span><span class="p">)</span>
|
||
<span class="go">'NaN'</span>
|
||
<span class="gp">>>> </span><span class="n">cmp</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="mi">23</span><span class="p">)</span>
|
||
<span class="go">-1</span>
|
||
<span class="gp">>>> </span><span class="n">cmp</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">nan</span><span class="p">)</span>
|
||
<span class="go">1</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>divide: Use operator <code class="docutils literal notranslate"><span class="pre">/</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'-15.67'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">/</span> <span class="mi">2</span>
|
||
<span class="go">Decimal('-7.835')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>divide-integer: Use operator <code class="docutils literal notranslate"><span class="pre">//</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'-15.67'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">//</span> <span class="mi">2</span>
|
||
<span class="go">Decimal('-7')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>max: Use method <code class="docutils literal notranslate"><span class="pre">max()</span></code>. Only use this method (and not the
|
||
built-in function max()) when dealing with <em>special values</em>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'15'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">nan</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'NaN'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
|
||
<span class="go">Decimal('15')</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">nan</span><span class="p">)</span>
|
||
<span class="go">Decimal('NaN')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>min: Use method <code class="docutils literal notranslate"><span class="pre">min()</span></code>. Only use this method (and not the
|
||
built-in function min()) when dealing with <em>special values</em>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'15'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">nan</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'NaN'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">min</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
|
||
<span class="go">Decimal('8')</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">min</span><span class="p">(</span><span class="n">nan</span><span class="p">)</span>
|
||
<span class="go">Decimal('NaN')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>minus: Use unary operator <code class="docutils literal notranslate"><span class="pre">-</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'-15.67'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="o">-</span><span class="n">d</span>
|
||
<span class="go">Decimal('15.67')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>plus: Use unary operator <code class="docutils literal notranslate"><span class="pre">+</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'-15.67'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="o">+</span><span class="n">d</span>
|
||
<span class="go">Decimal('-15.67')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>multiply: Use operator <code class="docutils literal notranslate"><span class="pre">*</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'5.7'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">*</span> <span class="mi">3</span>
|
||
<span class="go">Decimal('17.1')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>normalize: Use method <code class="docutils literal notranslate"><span class="pre">normalize()</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'123.45000'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">normalize</span><span class="p">()</span>
|
||
<span class="go">Decimal('123.45')</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'120.00'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">normalize</span><span class="p">()</span>
|
||
<span class="go">Decimal('1.2E+2')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>quantize: Use method <code class="docutils literal notranslate"><span class="pre">quantize()</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'2.17'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">quantize</span><span class="p">(</span><span class="n">Decimal</span><span class="p">(</span><span class="s1">'0.001'</span><span class="p">))</span>
|
||
<span class="go">Decimal('2.170')</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">quantize</span><span class="p">(</span><span class="n">Decimal</span><span class="p">(</span><span class="s1">'0.1'</span><span class="p">))</span>
|
||
<span class="go">Decimal('2.2')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>remainder: Use operator <code class="docutils literal notranslate"><span class="pre">%</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'10'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">%</span> <span class="mi">3</span>
|
||
<span class="go">Decimal('1')</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">%</span> <span class="mi">6</span>
|
||
<span class="go">Decimal('4')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>remainder-near: Use method <code class="docutils literal notranslate"><span class="pre">remainder_near()</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'10'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">remainder_near</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
|
||
<span class="go">Decimal('1')</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">remainder_near</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
|
||
<span class="go">Decimal('-2')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>round-to-integral-value: Use method <code class="docutils literal notranslate"><span class="pre">to_integral()</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'-123.456'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">to_integral</span><span class="p">()</span>
|
||
<span class="go">Decimal('-123')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>same-quantum: Use method <code class="docutils literal notranslate"><span class="pre">same_quantum()</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'123.456'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">same_quantum</span><span class="p">(</span><span class="n">Decimal</span><span class="p">(</span><span class="s1">'0.001'</span><span class="p">))</span>
|
||
<span class="go">True</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">same_quantum</span><span class="p">(</span><span class="n">Decimal</span><span class="p">(</span><span class="s1">'0.01'</span><span class="p">))</span>
|
||
<span class="go">False</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>square-root: Use method <code class="docutils literal notranslate"><span class="pre">sqrt()</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'123.456'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">sqrt</span><span class="p">()</span>
|
||
<span class="go">Decimal('11.1110756')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>power: User operator <code class="docutils literal notranslate"><span class="pre">**</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'12.56'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">**</span> <span class="mi">2</span>
|
||
<span class="go">Decimal('157.7536')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<p>Following are other methods and why they exist:</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">adjusted()</span></code>: Returns the adjusted exponent. This concept is
|
||
defined in the Spec: the adjusted exponent is the value of the
|
||
exponent of a number when that number is expressed as though in
|
||
scientific notation with one digit before any decimal point:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'12.56'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">adjusted</span><span class="p">()</span>
|
||
<span class="go">1</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">from_float()</span></code>: Class method to create instances from float data
|
||
types:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="o">.</span><span class="n">from_float</span><span class="p">(</span><span class="mf">12.35</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span>
|
||
<span class="go">Decimal('12.3500000')</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">as_tuple()</span></code>: Show the internal structure of the Decimal, the
|
||
triple tuple. This method is not required by the Spec, but Tim
|
||
Peters proposed it and the community agreed to have it (it’s useful
|
||
for developing and debugging):<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'123.4'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">as_tuple</span><span class="p">()</span>
|
||
<span class="go">(0, (1, 2, 3, 4), -1)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="s1">'-2.34e5'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">as_tuple</span><span class="p">()</span>
|
||
<span class="go">(1, (2, 3, 4), 3)</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section id="context-attributes">
|
||
<h3><a class="toc-backref" href="#context-attributes" role="doc-backlink">Context Attributes</a></h3>
|
||
<p>These are the attributes that can be changed to modify the context.</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">prec</span></code> (int): the precision:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">prec</span>
|
||
<span class="go">9</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">rounding</span></code> (str): rounding type (how to round):<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">rounding</span>
|
||
<span class="go">'half_even'</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">trap_enablers</span></code> (dict): if trap_enablers[exception] = 1, then an
|
||
exception is raised when it is caused:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">trap_enablers</span><span class="p">[</span><span class="n">Underflow</span><span class="p">]</span>
|
||
<span class="go">0</span>
|
||
<span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">trap_enablers</span><span class="p">[</span><span class="n">Clamped</span><span class="p">]</span>
|
||
<span class="go">0</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">flags</span></code> (dict): when an exception is caused, flags[exception] is
|
||
incremented (whether or not the trap_enabler is set). Should be
|
||
reset by the user of Decimal instance:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">flags</span><span class="p">[</span><span class="n">Underflow</span><span class="p">]</span>
|
||
<span class="go">0</span>
|
||
<span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">flags</span><span class="p">[</span><span class="n">Clamped</span><span class="p">]</span>
|
||
<span class="go">0</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">Emin</span></code> (int): minimum exponent:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">Emin</span>
|
||
<span class="go">-999999999</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">Emax</span></code> (int): maximum exponent:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">Emax</span>
|
||
<span class="go">999999999</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">capitals</span></code> (int): boolean flag to use ‘E’ (True/1) or ‘e’
|
||
(False/0) in the string (for example, ‘1.32e+2’ or ‘1.32E+2’):<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">capitals</span>
|
||
<span class="go">1</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section id="context-methods">
|
||
<h3><a class="toc-backref" href="#context-methods" role="doc-backlink">Context Methods</a></h3>
|
||
<p>The following methods comply with Decimal functionality from the Spec.
|
||
Be aware that the operations that are called through a specific
|
||
context use that context and not the thread context.</p>
|
||
<p>To use these methods, take note that the syntax changes when the
|
||
operator is binary or unary, for example:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">mycontext</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">Decimal</span><span class="p">(</span><span class="s1">'-2'</span><span class="p">))</span>
|
||
<span class="go">'2'</span>
|
||
<span class="gp">>>> </span><span class="n">mycontext</span><span class="o">.</span><span class="n">multiply</span><span class="p">(</span><span class="n">Decimal</span><span class="p">(</span><span class="s1">'2.3'</span><span class="p">),</span> <span class="mi">5</span><span class="p">)</span>
|
||
<span class="go">'11.5'</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>So, the following are the Spec operations and conversions and how to
|
||
achieve them through a context (where <code class="docutils literal notranslate"><span class="pre">d</span></code> is a Decimal instance and
|
||
<code class="docutils literal notranslate"><span class="pre">n</span></code> a number that can be used in an <a class="reference internal" href="#implicit-construction">Implicit construction</a>):</p>
|
||
<ul class="simple">
|
||
<li>to-scientific-string: <code class="docutils literal notranslate"><span class="pre">to_sci_string(d)</span></code></li>
|
||
<li>to-engineering-string: <code class="docutils literal notranslate"><span class="pre">to_eng_string(d)</span></code></li>
|
||
<li>to-number: <code class="docutils literal notranslate"><span class="pre">create_decimal(number)</span></code>, see <a class="reference internal" href="#explicit-construction">Explicit construction</a>
|
||
for <code class="docutils literal notranslate"><span class="pre">number</span></code>.</li>
|
||
<li>abs: <code class="docutils literal notranslate"><span class="pre">abs(d)</span></code></li>
|
||
<li>add: <code class="docutils literal notranslate"><span class="pre">add(d,</span> <span class="pre">n)</span></code></li>
|
||
<li>subtract: <code class="docutils literal notranslate"><span class="pre">subtract(d,</span> <span class="pre">n)</span></code></li>
|
||
<li>compare: <code class="docutils literal notranslate"><span class="pre">compare(d,</span> <span class="pre">n)</span></code></li>
|
||
<li>divide: <code class="docutils literal notranslate"><span class="pre">divide(d,</span> <span class="pre">n)</span></code></li>
|
||
<li>divide-integer: <code class="docutils literal notranslate"><span class="pre">divide_int(d,</span> <span class="pre">n)</span></code></li>
|
||
<li>max: <code class="docutils literal notranslate"><span class="pre">max(d,</span> <span class="pre">n)</span></code></li>
|
||
<li>min: <code class="docutils literal notranslate"><span class="pre">min(d,</span> <span class="pre">n)</span></code></li>
|
||
<li>minus: <code class="docutils literal notranslate"><span class="pre">minus(d)</span></code></li>
|
||
<li>plus: <code class="docutils literal notranslate"><span class="pre">plus(d)</span></code></li>
|
||
<li>multiply: <code class="docutils literal notranslate"><span class="pre">multiply(d,</span> <span class="pre">n)</span></code></li>
|
||
<li>normalize: <code class="docutils literal notranslate"><span class="pre">normalize(d)</span></code></li>
|
||
<li>quantize: <code class="docutils literal notranslate"><span class="pre">quantize(d,</span> <span class="pre">d)</span></code></li>
|
||
<li>remainder: <code class="docutils literal notranslate"><span class="pre">remainder(d)</span></code></li>
|
||
<li>remainder-near: <code class="docutils literal notranslate"><span class="pre">remainder_near(d)</span></code></li>
|
||
<li>round-to-integral-value: <code class="docutils literal notranslate"><span class="pre">to_integral(d)</span></code></li>
|
||
<li>same-quantum: <code class="docutils literal notranslate"><span class="pre">same_quantum(d,</span> <span class="pre">d)</span></code></li>
|
||
<li>square-root: <code class="docutils literal notranslate"><span class="pre">sqrt(d)</span></code></li>
|
||
<li>power: <code class="docutils literal notranslate"><span class="pre">power(d,</span> <span class="pre">n)</span></code></li>
|
||
</ul>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">divmod(d,</span> <span class="pre">n)</span></code> method supports decimal functionality through
|
||
Context.</p>
|
||
<p>These are methods that return useful information from the Context:</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">Etiny()</span></code>: Minimum exponent considering precision.<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">Emin</span>
|
||
<span class="go">-999999999</span>
|
||
<span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">Etiny</span><span class="p">()</span>
|
||
<span class="go">-1000000007</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">Etop()</span></code>: Maximum exponent considering precision.<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">Emax</span>
|
||
<span class="go">999999999</span>
|
||
<span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">Etop</span><span class="p">()</span>
|
||
<span class="go">999999991</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">copy()</span></code>: Returns a copy of the context.</li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
<section id="reference-implementation">
|
||
<h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2>
|
||
<p>As of Python 2.4-alpha, the code has been checked into the standard
|
||
library. The latest version is available from:</p>
|
||
<p><a class="reference external" href="http://svn.python.org/view/python/trunk/Lib/decimal.py">http://svn.python.org/view/python/trunk/Lib/decimal.py</a></p>
|
||
<p>The test cases are here:</p>
|
||
<p><a class="reference external" href="http://svn.python.org/view/python/trunk/Lib/test/test_decimal.py">http://svn.python.org/view/python/trunk/Lib/test/test_decimal.py</a></p>
|
||
</section>
|
||
<section id="references">
|
||
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
|
||
<aside class="footnote-list brackets">
|
||
<aside class="footnote brackets" id="id19" role="doc-footnote">
|
||
<dt class="label" id="id19">[1]<em> (<a href='#id1'>1</a>, <a href='#id8'>2</a>) </em></dt>
|
||
<dd>ANSI standard X3.274-1996 (Programming Language REXX):
|
||
<a class="reference external" href="http://www.rexxla.org/Standards/ansi.html">http://www.rexxla.org/Standards/ansi.html</a></aside>
|
||
<aside class="footnote brackets" id="id20" role="doc-footnote">
|
||
<dt class="label" id="id20">[2]<em> (<a href='#id2'>1</a>, <a href='#id3'>2</a>, <a href='#id5'>3</a>, <a href='#id6'>4</a>, <a href='#id11'>5</a>, <a href='#id12'>6</a>, <a href='#id13'>7</a>, <a href='#id14'>8</a>) </em></dt>
|
||
<dd>General Decimal Arithmetic specification (Cowlishaw):
|
||
<a class="reference external" href="http://speleotrove.com/decimal/decarith.html">http://speleotrove.com/decimal/decarith.html</a> (related
|
||
documents and links at <a class="reference external" href="http://speleotrove.com/decimal/">http://speleotrove.com/decimal/</a>)</aside>
|
||
<aside class="footnote brackets" id="id21" role="doc-footnote">
|
||
<dt class="label" id="id21">[<a href="#id7">3</a>]</dt>
|
||
<dd>ANSI/IEEE standard 854-1987 (Radix-Independent Floating-Point
|
||
Arithmetic):
|
||
<a class="reference external" href="http://www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html">http://www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html</a>
|
||
(unofficial text; official copies can be ordered from
|
||
<a class="reference external" href="http://standards.ieee.org/catalog/ordering.html">http://standards.ieee.org/catalog/ordering.html</a>)</aside>
|
||
<aside class="footnote brackets" id="id22" role="doc-footnote">
|
||
<dt class="label" id="id22">[<a href="#id4">4</a>]</dt>
|
||
<dd>Tim Peter’s FixedPoint at SourceForge:
|
||
<a class="reference external" href="http://fixedpoint.sourceforge.net/">http://fixedpoint.sourceforge.net/</a></aside>
|
||
<aside class="footnote brackets" id="id23" role="doc-footnote">
|
||
<dt class="label" id="id23">[<a href="#id9">5</a>]</dt>
|
||
<dd>IEEE 754 revision:
|
||
<a class="reference external" href="http://grouper.ieee.org/groups/754/revision.html">http://grouper.ieee.org/groups/754/revision.html</a></aside>
|
||
<aside class="footnote brackets" id="id24" role="doc-footnote">
|
||
<dt class="label" id="id24">[<a href="#id10">6</a>]</dt>
|
||
<dd>IEEE 754 references:
|
||
<a class="reference external" href="http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html">http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html</a></aside>
|
||
</aside>
|
||
</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-0327.rst">https://github.com/python/peps/blob/main/peps/pep-0327.rst</a></p>
|
||
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0327.rst">2023-09-09 17:39:29 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="#motivation">Motivation</a><ul>
|
||
<li><a class="reference internal" href="#the-problem-with-binary-float">The problem with binary float</a></li>
|
||
<li><a class="reference internal" href="#why-floating-point">Why floating point?</a></li>
|
||
<li><a class="reference internal" href="#why-not-rational">Why not rational?</a></li>
|
||
<li><a class="reference internal" href="#so-what-do-we-have">So, what do we have?</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#general-decimal-arithmetic-specification">General Decimal Arithmetic Specification</a><ul>
|
||
<li><a class="reference internal" href="#the-arithmetic-model">The Arithmetic Model</a></li>
|
||
<li><a class="reference internal" href="#numbers">Numbers</a></li>
|
||
<li><a class="reference internal" href="#context">Context</a></li>
|
||
<li><a class="reference internal" href="#default-contexts">Default Contexts</a></li>
|
||
<li><a class="reference internal" href="#exceptional-conditions">Exceptional Conditions</a></li>
|
||
<li><a class="reference internal" href="#rounding-algorithms">Rounding Algorithms</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#rationale">Rationale</a><ul>
|
||
<li><a class="reference internal" href="#explicit-construction">Explicit construction</a><ul>
|
||
<li><a class="reference internal" href="#from-int-or-long">From int or long</a></li>
|
||
<li><a class="reference internal" href="#from-string">From string</a></li>
|
||
<li><a class="reference internal" href="#from-float">From float</a></li>
|
||
<li><a class="reference internal" href="#from-tuples">From tuples</a></li>
|
||
<li><a class="reference internal" href="#from-decimal">From Decimal</a></li>
|
||
<li><a class="reference internal" href="#syntax-for-all-cases">Syntax for All Cases</a></li>
|
||
<li><a class="reference internal" href="#creating-from-context">Creating from Context</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#implicit-construction">Implicit construction</a><ul>
|
||
<li><a class="reference internal" href="#id15">From int or long</a></li>
|
||
<li><a class="reference internal" href="#id16">From string</a></li>
|
||
<li><a class="reference internal" href="#id17">From float</a></li>
|
||
<li><a class="reference internal" href="#id18">From Decimal</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#use-of-context">Use of Context</a></li>
|
||
<li><a class="reference internal" href="#python-usability">Python Usability</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#documentation">Documentation</a><ul>
|
||
<li><a class="reference internal" href="#decimal-attributes">Decimal Attributes</a></li>
|
||
<li><a class="reference internal" href="#decimal-methods">Decimal Methods</a></li>
|
||
<li><a class="reference internal" href="#context-attributes">Context Attributes</a></li>
|
||
<li><a class="reference internal" href="#context-methods">Context Methods</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
|
||
<li><a class="reference internal" href="#references">References</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-0327.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> |