5.6 decimal -- Decimal floating point arithmetic

# 5.6 `decimal` -- Decimal floating point arithmetic

New in version 2.4.

The `decimal` module provides support for decimal floating point arithmetic. It offers several advantages over the `float()` datatype:

- Decimal numbers can be represented exactly. In contrast, numbers like `1.1` do not have an exact representation in binary floating point. End users typically would not expect `1.1` to display as `1.1000000000000001` as it does with binary floating point.

- The exactness carries over into arithmetic. In decimal floating point, "`0.1 + 0.1 + 0.1 - 0.3`" is exactly equal to zero. In binary floating point, result is `5.5511151231257827e-017`. While near to zero, the differences prevent reliable equality testing and differences can accumulate. For this reason, decimal would be preferred in accounting applications which have strict equality invariants.

- The decimal module incorporates notion of significant places so that "`1.30 + 1.20`" is `2.50`. The trailing zero is kept to indicate significance. This is the customary presentation for monetary applications. For multiplication, the ``schoolbook'' approach uses all the figures in the multiplicands. For instance, "`1.3 * 1.2`" gives `1.56` while "`1.30 * 1.20`" gives `1.5600`.

- Unlike hardware based binary floating point, the decimal module has a user settable precision (defaulting to 28 places) which can be as large as needed for a given problem:

      >>> getcontext().prec = 6
      >>> Decimal(1) / Decimal(7)
      Decimal("0.142857")
      >>> getcontext().prec = 28
      >>> Decimal(1) / Decimal(7)
      Decimal("0.1428571428571428571428571429")

- Both binary and decimal floating point are implemented in terms of published standards. While the built-in float type exposes only a modest portion of its capabilities, the decimal module exposes all required parts of the standard. When needed, the programmer has full control over rounding and signal handling.

The module design is centered around three concepts: the decimal number, the context for arithmetic, and signals.

A decimal number is immutable. It has a sign, coefficient digits, and an exponent. To preserve significance, the coefficient digits do not truncate trailing zeroes. Decimals also include special values such as `Infinity`, `-Infinity`, and `NaN`. The standard also differentiates `-0` from `+0`.

The context for arithmetic is an environment specifying precision, rounding rules, limits on exponents, flags indicating the results of operations, and trap enablers which determine whether signals are treated as exceptions. Rounding options include `ROUND_CEILING`, `ROUND_DOWN`, `ROUND_FLOOR`, `ROUND_HALF_DOWN`, `ROUND_HALF_EVEN`, `ROUND_HALF_UP`, and `ROUND_UP`.

Signals are groups of exceptional conditions arising during the course of computation. Depending on the needs of the application, signals may be ignored, considered as informational, or treated as exceptions. The signals in the decimal module are: `Clamped`, `InvalidOperation`, `DivisionByZero`, `Inexact`, `Rounded`, `Subnormal`, `Overflow`, and `Underflow`.

For each signal there is a flag and a trap enabler. When a signal is encountered, its flag incremented from zero and, then, if the trap enabler is set to one, an exception is raised. Flags are sticky, so the user needs to reset them before monitoring a calculation.

See Also:

IBM's General Decimal Arithmetic Specification, The General Decimal Arithmetic Specification.

IEEE standard 854-1987, Unofficial IEEE 854 Text.