# `decimal` — Decimal fixed point and floating point arithmetic

Вихідний код: Lib/decimal.py

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

- Decimal «базується на моделі з плаваючою комою, яка була розроблена з урахуванням людей, і обов’язково має головний керівний принцип - комп’ютери повинні забезпечувати арифметику, яка працює так само, як арифметика, яку люди вивчають у школі». – витяг із специфікації десяткової арифметики.

- Decimal numbers can be represented exactly. In contrast, numbers like `1.1` and `2.2` do not have exact representations in binary floating point. End users typically would not expect `1.1 + 2.2` to display as `3.3000000000000003` 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, the result is `5.5511151231257827e-017`. While near to zero, the differences prevent reliable equality testing and differences can accumulate. For this reason, decimal is preferred in accounting applications which have strict equality invariants.

- The decimal module incorporates a 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`.

- На відміну від двійкового числа з плаваючою комою на апаратній основі, десятковий модуль має змінну користувачем точність (за замовчуванням 28 знаків), яка може бути настільки великою, наскільки це потрібно для даної проблеми:

      >>> from decimal import *
      >>> getcontext().prec = 6
      >>> Decimal(1) / Decimal(7)
      Decimal('0.142857')
      >>> getcontext().prec = 28
      >>> Decimal(1) / Decimal(7)
      Decimal('0.1428571428571428571428571429')

- І двійкові, і десяткові числа з плаваючою комою реалізовані відповідно до опублікованих стандартів. У той час як вбудований тип float відкриває лише скромну частину своїх можливостей, десятковий модуль відкриває всі необхідні частини стандарту. За потреби програміст має повний контроль над округленням і обробкою сигналу. Це включає в себе опцію для застосування точної арифметики за допомогою винятків для блокування будь-яких неточних операцій.

- Десятковий модуль був розроблений для підтримки «без шкоди як точної неокругленої десяткової арифметики (іноді її називають арифметикою з фіксованою комою), так і округленої арифметики з плаваючою комою». – витяг із специфікації десяткової арифметики.

Конструкція модуля зосереджена навколо трьох понять: десяткове число, контекст для арифметики та сигнали.

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

Контекст для арифметики — це середовище, що визначає точність, правила округлення, обмеження на експоненти, прапори, що вказують результати операцій, і засоби перехоплення, які визначають, чи розглядаються сигнали як винятки. Параметри округлення включають `ROUND_CEILING`, `ROUND_DOWN`, `ROUND_FLOOR`, `ROUND_HALF_DOWN`, `ROUND_HALF_EVEN`, `ROUND_HALF_UP`, `ROUND_UP` і `ROUND_05UP`.

Сигнали - це групи виняткових умов, що виникають під час обчислень. Залежно від потреб програми, сигнали можуть ігноруватися, розглядатися як інформаційні або розглядатися як винятки. Сигнали в десятковому модулі: `Clamped`, `InvalidOperation`, `DivisionByZero`, `Inexact`, `Rounded`, `Subnormal`, `Overflow`, `Underflow` і `FloatOperation`.

Для кожного сигналу є прапорець і активатор пастки. Коли зустрічається сигнал, його прапорець встановлюється на одиницю, тоді, якщо активатор перехоплення встановлений на одиницю, виникає виняток. Прапори є липкими, тому користувачеві потрібно скинути їх, перш ніж контролювати обчислення.

Дивись також

- IBM’s General Decimal Arithmetic Specification, The General Decimal Arithmetic Specification.

## Короткий підручник

Звичайним початком використання десяткових дробів є імпортування модуля, перегляд поточного контексту за допомогою `getcontext()` і, якщо необхідно, встановлення нових значень для точності, округлення або ввімкнення перехоплень:

    >>> from decimal import *
    >>> getcontext()
    Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
            capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero,
            InvalidOperation])

    >>> getcontext().prec = 7       # Set a new precision

Decimal instances can be constructed from integers, strings, floats, or tuples. Construction from an integer or a float performs an exact conversion of the value of that integer or float. Decimal numbers include special values such as `NaN` which stands for «Not a number», positive and negative `Infinity`, and `-0`:

    >>> getcontext().prec = 28
    >>> Decimal(10)
    Decimal('10')
    >>> Decimal('3.14')
    Decimal('3.14')
    >>> Decimal(3.14)
    Decimal('3.140000000000000124344978758017532527446746826171875')
    >>> Decimal((0, (3, 1, 4), -2))
    Decimal('3.14')
    >>> Decimal(str(2.0 ** 0.5))
    Decimal('1.4142135623730951')
    >>> Decimal(2) ** Decimal('0.5')
    Decimal('1.414213562373095048801688724')
    >>> Decimal('NaN')
    Decimal('NaN')
    >>> Decimal('-Infinity')
    Decimal('-Infinity')

Якщо сигнал `FloatOperation` перехоплюється, випадкове змішування десяткових дробів і чисел з плаваючою точкою в конструкторах або впорядкованих порівняннях викликає виняток:

    >>> c = getcontext()
    >>> c.traps[FloatOperation] = True
    >>> Decimal(3.14)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
    >>> Decimal('3.5') < 3.7
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
    >>> Decimal('3.5') == 3.5
    True

Нове в версії 3.3.

Значення нового десяткового дробу визначається виключно кількістю введених цифр. Точність контексту та округлення застосовуються лише під час арифметичних операцій.

    >>> getcontext().prec = 6
    >>> Decimal('3.0')
    Decimal('3.0')
    >>> Decimal('3.1415926535')
    Decimal('3.1415926535')
    >>> Decimal('3.1415926535') + Decimal('2.7182818285')
    Decimal('5.85987')
    >>> getcontext().rounding = ROUND_UP
    >>> Decimal('3.1415926535') + Decimal('2.7182818285')
    Decimal('5.85988')

Якщо внутрішні обмеження версії C перевищено, побудова десяткового числа призводить до `InvalidOperation`:

    >>> Decimal("1e9999999999999999999")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

Змінено в версії 3.3.

Decimals interact well with much of the rest of Python. Here is a small decimal floating point flying circus:

    >>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
    >>> max(data)
    Decimal('9.25')
    >>> min(data)
    Decimal('0.03')
    >>> sorted(data)
    [Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
     Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
    >>> sum(data)
    Decimal('19.29')
    >>> a,b,c = data[:3]
    >>> str(a)
    '1.34'
    >>> float(a)
    1.34
    >>> round(a, 1)
    Decimal('1.3')
    >>> int(a)
    1
    >>> a * 5
    Decimal('6.70')
    >>> a * b
    Decimal('2.5058')
    >>> c % a
    Decimal('0.77')

І деякі математичні функції також доступні для Decimal:

    >>> getcontext().prec = 28
    >>> Decimal(2).sqrt()
    Decimal('1.414213562373095048801688724')
    >>> Decimal(1).exp()
    Decimal('2.718281828459045235360287471')
    >>> Decimal('10').ln()
    Decimal('2.302585092994045684017991455')
    >>> Decimal('10').log10()
    Decimal('1')

The `quantize()` method rounds a number to a fixed exponent. This method is useful for monetary applications that often round results to a fixed number of places:

    >>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
    Decimal('7.32')
    >>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
    Decimal('8')

Як показано вище, функція `getcontext()` отримує доступ до поточного контексту та дозволяє змінювати налаштування. Такий підхід відповідає потребам більшості програм.

Для більш складної роботи може бути корисним створити альтернативні контексти за допомогою конструктора Context(). Щоб зробити альтернативу активною, використовуйте функцію `setcontext()`.

Відповідно до стандарту, модуль `decimal` надає два готові до використання стандартні контексти, `BasicContext` і `ExtendedContext`. Перший особливо корисний для налагодження, оскільки багато пасток увімкнено:

    >>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
    >>> setcontext(myothercontext)
    >>> Decimal(1) / Decimal(7)
    Decimal('0.142857142857142857142857142857142857142857142857142857142857')

    >>> ExtendedContext
    Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
            capitals=1, clamp=0, flags=[], traps=[])
    >>> setcontext(ExtendedContext)
    >>> Decimal(1) / Decimal(7)
    Decimal('0.142857143')
    >>> Decimal(42) / Decimal(0)
    Decimal('Infinity')

    >>> setcontext(BasicContext)
    >>> Decimal(42) / Decimal(0)
    Traceback (most recent call last):
      File "<pyshell#143>", line 1, in -toplevel-
        Decimal(42) / Decimal(0)
    DivisionByZero: x / 0

Contexts also have signal flags for monitoring exceptional conditions encountered during computations. The flags remain set until explicitly cleared, so it is best to clear the flags before each set of monitored computations by using the `clear_flags()` method.

    >>> setcontext(ExtendedContext)
    >>> getcontext().clear_flags()
    >>> Decimal(355) / Decimal(113)
    Decimal('3.14159292')
    >>> getcontext()
    Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
            capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])

The flags entry shows that the rational approximation to pi was rounded (digits beyond the context precision were thrown away) and that the result is inexact (some of the discarded digits were non-zero).

Individual traps are set using the dictionary in the `traps` attribute of a context:

    >>> setcontext(ExtendedContext)
    >>> Decimal(1) / Decimal(0)
    Decimal('Infinity')
    >>> getcontext().traps[DivisionByZero] = 1
    >>> Decimal(1) / Decimal(0)
    Traceback (most recent call last):
      File "<pyshell#112>", line 1, in -toplevel-
        Decimal(1) / Decimal(0)
    DivisionByZero: x / 0

Більшість програм коригують поточний контекст лише один раз, на початку програми. І в багатьох програмах дані перетворюються на `Decimal` за допомогою одного приведення всередині циклу. З набором контексту та створеними десятковими знаками основна частина програми маніпулює даними не інакше, як з іншими числовими типами Python.

## Десяткові об’єкти

class decimal.Decimal(value='0', context=None)

  Створіть новий об’єкт `Decimal` на основі value.

  значення може бути цілим числом, рядком, кортежем, `float` або іншим об’єктом `Decimal`. Якщо значення не вказано, повертає `Decimal('0')`. Якщо значення є рядком, воно має відповідати синтаксису десяткового числового рядка після видалення початкових і кінцевих пробілів, а також символів підкреслення:

      sign           ::=  '+' | '-'
      digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
      indicator      ::=  'e' | 'E'
      digits         ::=  digit [digit]...
      decimal-part   ::=  digits '.' [digits] | ['.'] digits
      exponent-part  ::=  indicator [sign] digits
      infinity       ::=  'Infinity' | 'Inf'
      nan            ::=  'NaN' [digits] | 'sNaN' [digits]
      numeric-value  ::=  decimal-part [exponent-part] | infinity
      numeric-string ::=  [sign] numeric-value | [sign] nan

  Other Unicode decimal digits are also permitted where `digit` appears above. These include decimal digits from various other alphabets (for example, Arabic-Indic and Devanāgarī digits) along with the fullwidth digits `'\uff10'` through `'\uff19'`.

  If value is a `tuple`, it should have three components, a sign (`0` for positive or `1` for negative), a `tuple` of digits, and an integer exponent. For example, `Decimal((0, (1, 4, 1, 4), -3))` returns `Decimal('1.414')`.

  If value is a `float`, the binary floating point value is losslessly converted to its exact decimal equivalent. This conversion can often require 53 or more digits of precision. For example, `Decimal(float('1.1'))` converts to `Decimal('1.100000000000000088817841970012523233890533447265625')`.

  Точність контексту не впливає на кількість збережених цифр. Це визначається виключно кількістю цифр у значенні. Наприклад, `Decimal('3.00000')` записує всі п’ять нулів, навіть якщо точність контексту становить лише три.

  The purpose of the context argument is determining what to do if value is a malformed string. If the context traps `InvalidOperation`, an exception is raised; otherwise, the constructor returns a new Decimal with the value of `NaN`.

  Після створення об’єкти `Decimal` є незмінними.

  Змінено в версії 3.2: Аргументом конструктора тепер дозволено бути екземпляром `float`.

  Змінено в версії 3.3: Аргументи `float` викликають виняток, якщо встановлено перехоплення `FloatOperation`. За замовчуванням перехоплення вимкнено.

  Змінено в версії 3.6: Підкреслення дозволено для групування, як і з інтегральними літералами та літералами з плаваючою комою в коді.

  Decimal floating point objects share many properties with the other built-in numeric types such as `float` and `int`. All of the usual math operations and special methods apply. Likewise, decimal objects can be copied, pickled, printed, used as dictionary keys, used as set elements, compared, sorted, and coerced to another type (such as `float` or `int`).

  Існують деякі невеликі відмінності між арифметикою на десяткових об’єктах і арифметикою на цілих числах і числах з плаваючою точкою. Коли оператор залишку `%` застосовується до десяткових об’єктів, знаком результату є знак діленого, а не знак дільника:

      >>> (-7) % 4
      1
      >>> Decimal(-7) % Decimal(4)
      Decimal('-3')

  Оператор цілочисельного ділення `//` поводиться аналогічно, повертаючи цілу частину справжньої частки (урізану до нуля), а не її нижню частину, щоб зберегти звичайну тотожність `x == (x // y) * y + x % y`:

      >>> -7 // 4
      -2
      >>> Decimal(-7) // Decimal(4)
      Decimal('-1')

  Оператори `%` і `//` реалізують операції `remainder` і `divide-integer` (відповідно), як описано в специфікації.

  Десяткові об’єкти зазвичай не можна поєднувати з числами з плаваючою точкою або екземплярами `fractions.Fraction` в арифметичних операціях: спроба додати `Decimal` до `float`, наприклад, призведе до `TypeError`. Однак можна використовувати оператори порівняння Python для порівняння `Decimal` екземпляра `x` з іншим числом `y`. Це дозволяє уникнути плутанини в результатах під час порівняння рівності між числами різних типів.

  Змінено в версії 3.2: Порівняння змішаного типу між екземплярами `Decimal` та іншими числовими типами тепер повністю підтримуються.

  In addition to the standard numeric properties, decimal floating point objects also have a number of specialized methods:

  adjusted()

    Повертає скоригований експонент після зміщення крайніх правих цифр коефіцієнта, доки не залишиться лише головна цифра: `Decimal('321e+5').adjusted()` повертає сім. Використовується для визначення позиції старшого розряду відносно коми.

  as_integer_ratio()

    Повертає пару `(n, d)` цілих чисел, які представляють даний екземпляр `Decimal` у вигляді дробу в найменших членах і з позитивним знаменником:

        >>> Decimal('-3.14').as_integer_ratio()
        (-157, 50)

    Перетворення точне. Викликайте OverflowError на нескінченності та ValueError на NaN.

  Нове в версії 3.6.

  as_tuple()

    Повертає представлення числа named tuple: `DecimalTuple(знак, цифри, експонента)`.

  canonical()

    Повертає канонічне кодування аргументу. Наразі кодування екземпляра `Decimal` завжди канонічне, тому ця операція повертає його аргумент без змін.

  compare(other, context=None)

    Порівняйте значення двох екземплярів Decimal. `compare()` повертає екземпляр Decimal, і якщо один із операндів є NaN, то результатом є NaN:

        a or b is a NaN  ==> Decimal('NaN')
        a < b            ==> Decimal('-1')
        a == b           ==> Decimal('0')
        a > b            ==> Decimal('1')

  compare_signal(other, context=None)

    Ця операція ідентична методу `compare()`, за винятком того, що сигналізують усі NaN. Тобто, якщо жоден операнд не є сигнальним NaN, тоді будь-який тихий NaN операнд розглядається як сигнальний NaN.

  compare_total(other, context=None)

    Порівняйте два операнди, використовуючи їх абстрактне представлення, а не числове значення. Подібно до методу `compare()`, але результат дає загальне впорядкування екземплярів `Decimal`. Два екземпляри `Decimal` з однаковим числовим значенням, але різними представленнями порівнюються нерівномірно в такому порядку:

        >>> Decimal('12.0').compare_total(Decimal('12'))
        Decimal('-1')

    Безшумні та сигнальні NaN також включені в загальне замовлення. Результатом цієї функції є `Decimal('0')`, якщо обидва операнди мають однакове представлення, `Decimal('-1')`, якщо перший операнд є нижчим у загальному порядку, ніж другий, і `Decimal('1')`, якщо перший операнд вищий у загальному порядку, ніж другий операнд. Дивіться специфікацію для детальної інформації про загальне замовлення.

    Ця операція не залежить від контексту та є тихою: прапорці не змінюються та округлення не виконується. Як виняток, версія C може викликати InvalidOperation, якщо другий операнд не може бути точно перетворений.

  compare_total_mag(other, context=None)

    Порівняйте два операнди, використовуючи їх абстрактне представлення, а не значення, як у `compare_total()`, але ігноруючи знак кожного операнда. `x.compare_total_mag(y)` еквівалентно `x.copy_abs().compare_total(y.copy_abs())`.

    Ця операція не залежить від контексту та є тихою: прапорці не змінюються та округлення не виконується. Як виняток, версія C може викликати InvalidOperation, якщо другий операнд не може бути точно перетворений.

  conjugate()

    Просто повертає self, цей метод призначений лише для відповідності десятковій специфікації.

  copy_abs()

    Повертає абсолютне значення аргументу. Ця операція не залежить від контексту та є тихою: прапорці не змінюються та округлення не виконується.

  copy_negate()

    Повернути заперечення аргументу. Ця операція не залежить від контексту та є тихою: прапорці не змінюються та округлення не виконується.

  copy_sign(other, context=None)

    Повертає копію першого операнда зі знаком, який збігається зі знаком другого операнда. Наприклад:

        >>> Decimal('2.3').copy_sign(Decimal('-1.5'))
        Decimal('-2.3')

    Ця операція не залежить від контексту та є тихою: прапорці не змінюються та округлення не виконується. Як виняток, версія C може викликати InvalidOperation, якщо другий операнд не може бути точно перетворений.

  exp(context=None)

    Повертає значення (натуральної) експоненціальної функції `e**x` за заданим числом. Результат правильно округлюється за допомогою режиму округлення `ROUND_HALF_EVEN`.

        >>> Decimal(1).exp()
        Decimal('2.718281828459045235360287471')
        >>> Decimal(321).exp()
        Decimal('2.561702493119680037517373933E+139')

  classmethod from_float(f)

    Альтернативний конструктор, який приймає лише екземпляри `float` або `int`.

    Note `Decimal.from_float(0.1)` is not the same as `Decimal('0.1')`. Since 0.1 is not exactly representable in binary floating point, the value is stored as the nearest representable value which is `0x1.999999999999ap-4`. That equivalent value in decimal is `0.1000000000000000055511151231257827021181583404541015625`.

    Примітка

    Починаючи з Python 3.2 і далі, екземпляр `Decimal` також можна створити безпосередньо з `float`.

        >>> Decimal.from_float(0.1)
        Decimal('0.1000000000000000055511151231257827021181583404541015625')
        >>> Decimal.from_float(float('nan'))
        Decimal('NaN')
        >>> Decimal.from_float(float('inf'))
        Decimal('Infinity')
        >>> Decimal.from_float(float('-inf'))
        Decimal('-Infinity')

    Нове в версії 3.1.

  fma(other, third, context=None)

    Злитий множення-додавання. Повертає self*other+third без округлення проміжного продукту self*other.

        >>> Decimal(2).fma(3, 5)
        Decimal('11')

  is_canonical()

    Повертає `True`, якщо аргумент є канонічним, і `False` в іншому випадку. Наразі екземпляр `Decimal` завжди є канонічним, тому ця операція завжди повертає `True`.

  is_finite()

    Повертає `True`, якщо аргумент є скінченним числом, і `False`, якщо аргументом є нескінченність або NaN.

  is_infinite()

    Повертає `True`, якщо аргумент є додатною або від’ємною нескінченністю, і `False` в іншому випадку.

  is_nan()

    Повертає `True`, якщо аргумент є (тихим або сигнальним) NaN, і `False` в іншому випадку.

  is_normal(context=None)

    Повертає `True`, якщо аргумент є звичайним кінцевим числом. Повертає `False`, якщо аргумент нульовий, субнормальний, нескінченний або NaN.

  is_qnan()

    Повертає `True`, якщо аргумент є тихим NaN, і `False` в іншому випадку.

  is_signed()

    Повертає `True`, якщо аргумент має негативний знак, і `False` в іншому випадку. Зауважте, що і нулі, і NaN можуть мати знаки.

  is_snan()

    Повертає `True`, якщо аргумент є сигнальним NaN, і `False` в іншому випадку.

  is_subnormal(context=None)

    Повертає `True`, якщо аргумент ненормальний, і `False` в іншому випадку.

  is_zero()

    Повертає `True`, якщо аргумент є (позитивним або від’ємним) нулем, і `False` в іншому випадку.

  ln(context=None)

    Повертає натуральний (за основою e) логарифм операнда. Результат правильно округлюється за допомогою режиму округлення `ROUND_HALF_EVEN`.

  log10(context=None)

    Повертає десятий логарифм операнда. Результат правильно округлюється за допомогою режиму округлення `ROUND_HALF_EVEN`.

  logb(context=None)

    Для відмінного від нуля числа поверніть скоригований експонент його операнда як екземпляр `Decimal`. Якщо операнд дорівнює нулю, повертається `Decimal('-Infinity')` і піднімається прапор `DivisionByZero`. Якщо операнд є нескінченністю, тоді повертається `Decimal('Infinity')`.

  logical_and(other, context=None)

    `logical_and()` — це логічна операція, яка приймає два логічних операнда (див. Логічні операнди). Результатом є порозрядне `і` двох операндів.

  logical_invert(context=None)

    `logical_invert()` є логічною операцією. Результатом є порозрядна інверсія операнда.

  logical_or(other, context=None)

    `logical_or()` — це логічна операція, яка приймає два логічних операнда (див. Логічні операнди). Результатом є порозрядне «або» двох операндів.

  logical_xor(other, context=None)

    `logical_xor()` — це логічна операція, яка приймає два логічних операнда (див. Логічні операнди). Результатом є розрядний виключний або двох операндів.

  max(other, context=None)

    Like `max(self, other)` except that the context rounding rule is applied before returning and that `NaN` values are either signaled or ignored (depending on the context and whether they are signaling or quiet).

  max_mag(other, context=None)

    Подібно до методу `max()`, але порівняння виконується з використанням абсолютних значень операндів.

  min(other, context=None)

    Like `min(self, other)` except that the context rounding rule is applied before returning and that `NaN` values are either signaled or ignored (depending on the context and whether they are signaling or quiet).

  min_mag(other, context=None)

    Подібно до методу `min()`, але порівняння виконується з використанням абсолютних значень операндів.

  next_minus(context=None)

    Повертає найбільше число, яке можна представити в заданому контексті (або в контексті поточного потоку, якщо контекст не задано), яке є меншим за заданий операнд.

  next_plus(context=None)

    Повертає найменше число, яке можна представити в заданому контексті (або в контексті поточного потоку, якщо контекст не задано), яке більше заданого операнда.

  next_toward(other, context=None)

    Якщо два операнди нерівні, поверніть число, найближче до першого операнду в напрямку другого операнда. Якщо обидва операнди чисельно рівні, поверніть копію першого операнда зі знаком, встановленим таким самим, як знак другого операнда.

  normalize(context=None)

    Used for producing canonical values of an equivalence class within either the current context or the specified context.

    This has the same semantics as the unary plus operation, except that if the final result is finite it is reduced to its simplest form, with all trailing zeros removed and its sign preserved. That is, while the coefficient is non-zero and a multiple of ten the coefficient is divided by ten and the exponent is incremented by 1. Otherwise (the coefficient is zero) the exponent is set to 0. In all cases the sign is unchanged.

    For example, `Decimal('32.100')` and `Decimal('0.321000e+2')` both normalize to the equivalent value `Decimal('32.1')`.

    Note that rounding is applied before reducing to simplest form.

    In the latest versions of the specification, this operation is also known as `reduce`.

  number_class(context=None)

    Повертає рядок, що описує клас операнда. Повернене значення є одним із наступних десяти рядків.

    - `"-Infinity"`, що вказує, що операнд є негативною нескінченністю.

    - `"-Normal"`, вказуючи, що операнд є від’ємним нормальним числом.

    - `"-Subnormal"`, що вказує на те, що операнд від’ємний і ненормальний.

    - `"-Zero"`, вказуючи, що операнд є від’ємним нулем.

    - `"+Zero"`, вказуючи, що операнд є позитивним нулем.

    - `"+Subnormal"`, що вказує, що операнд є додатним і субнормальним.

    - `"+Normal"`, вказуючи, що операнд є додатним нормальним числом.

    - `"+Infinity"`, що вказує, що операнд є позитивною нескінченністю.

    - `"NaN"`, вказуючи, що операнд є тихим NaN (не числом).

    - `"sNaN"`, вказуючи, що операнд є сигнальним NaN.

  quantize(exp, rounding=None, context=None)

    Повертає значення, що дорівнює першому операнду після округлення та має експоненту другого операнда.

        >>> Decimal('1.41421356').quantize(Decimal('1.000'))
        Decimal('1.414')

    На відміну від інших операцій, якщо довжина коефіцієнта після операції квантування буде більшою за точність, тоді сигналізується `InvalidOperation`. Це гарантує, що, якщо немає умови помилки, квантований показник степеня завжди дорівнює показнику правого операнда.

    Крім того, на відміну від інших операцій, квантування ніколи не сигналізує про переповнення, навіть якщо результат ненормальний і неточний.

    Якщо експонента другого операнда більша, ніж експонента першого, може знадобитися округлення. У цьому випадку режим округлення визначається аргументом `округлення`, якщо задано, інакше заданим аргументом `контексту`; якщо жоден аргумент не задано, використовується режим округлення контексту поточного потоку.

    An error is returned whenever the resulting exponent is greater than `Emax` or less than `Etiny()`.

  radix()

    Повертає `Decimal(10)`, основу (базу), у якій клас `Decimal` виконує всю свою арифметику. Включено для сумісності зі специфікацією.

  remainder_near(other, context=None)

    Повертає залишок від ділення self на other. Це відрізняється від `self % other` тим, що знак залишку вибрано таким чином, щоб мінімізувати його абсолютне значення. Точніше, повертається значення `self - n * other`, де `n` є цілим числом, найближчим до точного значення `self / other`, і якщо два цілі числа однаково близькі, то парне вибрано.

    Якщо результат дорівнює нулю, то його знак буде знаком self.

        >>> Decimal(18).remainder_near(Decimal(10))
        Decimal('-2')
        >>> Decimal(25).remainder_near(Decimal(10))
        Decimal('5')
        >>> Decimal(35).remainder_near(Decimal(10))
        Decimal('-5')

  rotate(other, context=None)

    Повертає результат повороту цифр першого операнда на величину, визначену другим операндом. Другий операнд має бути цілим числом у діапазоні від точності до точності. Абсолютне значення другого операнда дає кількість місць для обертання. Якщо другий операнд додатний, то обертання відбувається вліво; інакше обертання праворуч. Коефіцієнт першого операнда доповнюється зліва нулями з точністю до довжини, якщо необхідно. Знак і експонента першого операнда не змінюються.

  same_quantum(other, context=None)

    Test whether self and other have the same exponent or whether both are `NaN`.

    Ця операція не залежить від контексту та є тихою: прапорці не змінюються та округлення не виконується. Як виняток, версія C може викликати InvalidOperation, якщо другий операнд не може бути точно перетворений.

  scaleb(other, context=None)

    Повертає перший операнд з експонентою, скоригованою другим. Аналогічно повертає перший операнд, помножений на `10**other`. Другий операнд має бути цілим числом.

  shift(other, context=None)

    Повертає результат зсуву цифр першого операнда на величину, визначену другим операндом. Другий операнд має бути цілим числом у діапазоні від точності до точності. Абсолютне значення другого операнда дає кількість місць для зсуву. Якщо другий операнд позитивний, то зсув виконується вліво; інакше зсув відбувається вправо. Цифри, зсунуті в коефіцієнт, є нулями. Знак і експонента першого операнда не змінюються.

  sqrt(context=None)

    Повертає квадратний корінь аргументу з повною точністю.

  to_eng_string(context=None)

    Перетворіть на рядок, використовуючи технічну нотацію, якщо потрібен експонент.

    Інженерна нотація має експоненту, кратну 3. Це може залишати до 3 цифр ліворуч від десяткового знака та може потребувати додавання одного або двох нулів у кінці.

    Наприклад, це перетворює `Decimal('123E+1')` на `Decimal('1.23E+3')`.

  to_integral(rounding=None, context=None)

    Ідентичний методу `to_integral_value()`. Ім’я `to_integral` було збережено для сумісності зі старими версіями.

  to_integral_exact(rounding=None, context=None)

    Округлити до найближчого цілого числа, сигналізуючи `Inexact` або `Rounded` відповідно, якщо відбувається округлення. Режим округлення визначається параметром `rounding`, якщо він заданий, інакше заданим `context`. Якщо жоден параметр не вказано, використовується режим округлення поточного контексту.

  to_integral_value(rounding=None, context=None)

    Округлення до найближчого цілого без сигналізації `Inexact` або `Rounded`. Якщо вказано, застосовує округлення; інакше використовує метод округлення або в наданому контексті, або в поточному контексті.

### Логічні операнди

The `logical_and()`, `logical_invert()`, `logical_or()`, and `logical_xor()` methods expect their arguments to be logical operands. A logical operand is a `Decimal` instance whose exponent and sign are both zero, and whose digits are all either `0` or `1`.

## Об’єкти контексту

Контексти - це середовища для арифметичних операцій. Вони керують точністю, встановлюють правила округлення, визначають, які сигнали розглядаються як винятки, і обмежують діапазон для експонент.

Кожен потік має власний поточний контекст, до якого можна отримати доступ або змінити його за допомогою функцій `getcontext()` і `setcontext()`:

decimal.getcontext()

  Повертає поточний контекст для активного потоку.

decimal.setcontext(c)

  Установіть поточний контекст для активного потоку на c.

Ви також можете використовувати оператор `with` і функцію `localcontext()`, щоб тимчасово змінити активний контекст.

decimal.localcontext(ctx=None, \*\*kwargs)

  Return a context manager that will set the current context for the active thread to a copy of ctx on entry to the with-statement and restore the previous context when exiting the with-statement. If no context is specified, a copy of the current context is used. The kwargs argument is used to set the attributes of the new context.

  Наприклад, наступний код встановлює поточну десяткову точність на 42 знаки, виконує обчислення, а потім автоматично відновлює попередній контекст:

      from decimal import localcontext

      with localcontext() as ctx:
          ctx.prec = 42   # Perform a high precision calculation
          s = calculate_something()
      s = +s  # Round the final result back to the default precision

  Using keyword arguments, the code would be the following:

      from decimal import localcontext

      with localcontext(prec=42) as ctx:
          s = calculate_something()
      s = +s

  Raises `TypeError` if kwargs supplies an attribute that `Context` doesn’t support. Raises either `TypeError` or `ValueError` if kwargs supplies an invalid value for an attribute.

  Змінено в версії 3.11: `localcontext()` now supports setting context attributes through the use of keyword arguments.

Нові контексти також можна створити за допомогою конструктора `Context`, описаного нижче. Крім того, модуль надає три готові контексти:

class decimal.BasicContext

  Це стандартний контекст, визначений Загальною специфікацією десяткової арифметики. Точність встановлена на дев’ять. Округлення встановлено на `ROUND_HALF_UP`. Усі прапори видалено. Усі перехоплення ввімкнено (розглядаються як винятки), крім `Inexact`, `Rounded` і `Subnormal`.

  Оскільки багато пасток увімкнено, цей контекст корисний для налагодження.

class decimal.ExtendedContext

  Це стандартний контекст, визначений Загальною специфікацією десяткової арифметики. Точність встановлена на дев’ять. Округлення встановлено на `ROUND_HALF_EVEN`. Усі прапори видалено. Перехоплення не ввімкнено (щоб винятки не виникали під час обчислень).

  Because the traps are disabled, this context is useful for applications that prefer to have result value of `NaN` or `Infinity` instead of raising exceptions. This allows an application to complete a run in the presence of conditions that would otherwise halt the program.

class decimal.DefaultContext

  Цей контекст використовується конструктором `Context` як прототип для нових контекстів. Зміна поля (така точність) призводить до зміни типового значення для нових контекстів, створених конструктором `Context`.

  Цей контекст найбільш корисний у багатопоточних середовищах. Зміна одного з полів перед запуском потоків призводить до встановлення загальносистемних значень за замовчуванням. Змінювати поля після початку потоків не рекомендується, оскільки це потребуватиме синхронізації потоків, щоб запобігти конкуренції.

  В однопотокових середовищах краще взагалі не використовувати цей контекст. Натомість просто створіть контексти явно, як описано нижче.

  The default values are `Context.prec`=`28`, `Context.rounding`=`ROUND_HALF_EVEN`, and enabled traps for `Overflow`, `InvalidOperation`, and `DivisionByZero`.

На додаток до трьох наданих контекстів, нові контексти можна створювати за допомогою конструктора `Context`.

class decimal.Context(prec=None, rounding=None, Emin=None, Emax=None, capitals=None, clamp=None, flags=None, traps=None)

  Створює новий контекст. Якщо поле не вказано або має значення `None`, значення за замовчуванням копіюються з `DefaultContext`. Якщо поле flags не вказано або має значення `None`, усі прапорці скидаються.

  prec is an integer in the range [`1`, `MAX_PREC`] that sets the precision for arithmetic operations in the context.

  Опція округлення є однією з констант, перелічених у розділі Режими округлення.

  У полях traps і flags перелічено всі сигнали, які потрібно встановити. Загалом, нові контексти мають лише встановлювати пастки та залишати прапорці вільними.

  The Emin and Emax fields are integers specifying the outer limits allowable for exponents. Emin must be in the range [`MIN_EMIN`, `0`], Emax in the range [`0`, `MAX_EMAX`].

  The capitals field is either `0` or `1` (the default). If set to `1`, exponents are printed with a capital `E`; otherwise, a lowercase `e` is used: `Decimal('6.02e+23')`.

  The clamp field is either `0` (the default) or `1`. If set to `1`, the exponent `e` of a `Decimal` instance representable in this context is strictly limited to the range `Emin - prec + 1 <= e <= Emax - prec + 1`. If clamp is `0` then a weaker condition holds: the adjusted exponent of the `Decimal` instance is at most `Emax`. When clamp is `1`, a large normal number will, where possible, have its exponent reduced and a corresponding number of zeros added to its coefficient, in order to fit the exponent constraints; this preserves the value of the number but loses information about significant trailing zeros. For example:

      >>> Context(prec=6, Emax=999, clamp=1).create_decimal('1.23e999')
      Decimal('1.23000E+999')

  A clamp value of `1` allows compatibility with the fixed-width decimal interchange formats specified in IEEE 754.

  The `Context` class defines several general purpose methods as well as a large number of methods for doing arithmetic directly in a given context. In addition, for each of the `Decimal` methods described above (with the exception of the `adjusted()` and `as_tuple()` methods) there is a corresponding `Context` method. For example, for a `Context` instance `C` and `Decimal` instance `x`, `C.exp(x)` is equivalent to `x.exp(context=C)`. Each `Context` method accepts a Python integer (an instance of `int`) anywhere that a Decimal instance is accepted.

  clear_flags()

    Resets all of the flags to `0`.

  clear_traps()

    Resets all of the traps to `0`.

    Нове в версії 3.3.

  copy()

    Повернути дублікат контексту.

  copy_decimal(num)

    Повернути копію екземпляра Decimal num.

  create_decimal(num)

    Створює новий екземпляр Decimal з num, але використовуючи self як контекст. На відміну від конструктора `Decimal`, до перетворення застосовуються точність контексту, метод округлення, прапорці та перехоплення.

    Це корисно, оскільки константи часто надаються з більшою точністю, ніж це потрібно програмі. Ще одна перевага полягає в тому, що округлення негайно усуває ненавмисні ефекти від цифр, що перевищують поточну точність. У наступному прикладі використання неокруглених вхідних даних означає, що додавання нуля до суми може змінити результат:

        >>> getcontext().prec = 3
        >>> Decimal('3.4445') + Decimal('1.0023')
        Decimal('4.45')
        >>> Decimal('3.4445') + Decimal(0) + Decimal('1.0023')
        Decimal('4.44')

    Цей метод реалізує операцію до числа специфікації IBM. Якщо аргумент є рядком, пробіли чи підкреслення на початку або в кінці не допускаються.

  create_decimal_from_float(f)

    Створює новий екземпляр Decimal із числа з плаваючою точкою f, але округляючи, використовуючи self як контекст. На відміну від методу класу `Decimal.from_float()`, до перетворення застосовуються точність контексту, метод округлення, прапорці та перехоплення.

        >>> context = Context(prec=5, rounding=ROUND_DOWN)
        >>> context.create_decimal_from_float(math.pi)
        Decimal('3.1415')
        >>> context = Context(prec=5, traps=[Inexact])
        >>> context.create_decimal_from_float(math.pi)
        Traceback (most recent call last):
            ...
        decimal.Inexact: None

    Нове в версії 3.1.

  Etiny()

    Повертає значення, що дорівнює `Emin - prec + 1`, що є мінімальним значенням експоненти для субнормальних результатів. Коли відбувається переповнення, експонента встановлюється на `Etiny`.

  Etop()

    Повертає значення, рівне `Emax - prec + 1`.

  Звичайним підходом до роботи з десятковими числами є створення `Decimal` екземплярів, а потім застосування арифметичних операцій, які виконуються в поточному контексті для активного потоку. Альтернативним підходом є використання контекстних методів для обчислення в конкретному контексті. Методи подібні до методів класу `Decimal` і тут лише коротко перераховані.

  abs(x)

    Повертає абсолютне значення x.

  add(x, y)

    Повертає суму x і y.

  canonical(x)

    Повертає той самий об’єкт Decimal x.

  compare(x, y)

    Чисельно порівнює x і y.

  compare_signal(x, y)

    Чисельно порівнює значення двох операндів.

  compare_total(x, y)

    Порівнює два операнди, використовуючи їх абстрактне представлення.

  compare_total_mag(x, y)

    Порівнює два операнди, використовуючи їх абстрактне представлення, ігноруючи знак.

  copy_abs(x)

    Повертає копію x зі знаком 0.

  copy_negate(x)

    Повертає копію x з перевернутим знаком.

  copy_sign(x, y)

    Копіює знак з y на x.

  divide(x, y)

    Повертає x, поділене на y.

  divide_int(x, y)

    Повертає x, поділене на y, усічене до цілого числа.

  divmod(x, y)

    Ділить два числа та повертає цілу частину результату.

  exp(x)

    Returns `e ** x`.

  fma(x, y, z)

    Повертає x, помножене на y, плюс z.

  is_canonical(x)

    Повертає `True`, якщо x канонічний; інакше повертає `False`.

  is_finite(x)

    Повертає `True`, якщо x є кінцевим; інакше повертає `False`.

  is_infinite(x)

    Повертає `True`, якщо x є нескінченним; інакше повертає `False`.

  is_nan(x)

    Повертає `True`, якщо x є qNaN або sNaN; інакше повертає `False`.

  is_normal(x)

    Повертає `True`, якщо x є нормальним числом; інакше повертає `False`.

  is_qnan(x)

    Повертає `True`, якщо x є тихим NaN; інакше повертає `False`.

  is_signed(x)

    Повертає `True`, якщо x від’ємне; інакше повертає `False`.

  is_snan(x)

    Повертає `True`, якщо x є сигнальним NaN; інакше повертає `False`.

  is_subnormal(x)

    Повертає `True`, якщо x є субнормальним; інакше повертає `False`.

  is_zero(x)

    Повертає `True`, якщо x дорівнює нулю; інакше повертає `False`.

  ln(x)

    Повертає натуральний (за основою e) логарифм x.

  log10(x)

    Повертає логарифм x за основою 10.

  logb(x)

    Повертає експоненту величини MSD операнда.

  logical_and(x, y)

    Застосовує логічну операцію і між цифрами кожного операнда.

  logical_invert(x)

    Інвертуйте всі цифри в x.

  logical_or(x, y)

    Застосовує логічну операцію або між цифрами кожного операнда.

  logical_xor(x, y)

    Застосовує логічну операцію xor між цифрами кожного операнда.

  max(x, y)

    Чисельно порівнює два значення та повертає максимальне значення.

  max_mag(x, y)

    Числово порівнює значення без урахування знака.

  min(x, y)

    Чисельно порівнює два значення та повертає мінімум.

  min_mag(x, y)

    Числово порівнює значення без урахування знака.

  minus(x)

    Мінус відповідає унарному префіксному оператору мінус у Python.

  multiply(x, y)

    Поверніть добуток x і y.

  next_minus(x)

    Повертає найбільше представлене число, менше за x.

  next_plus(x)

    Повертає найменше число, яке можна представити, більше за x.

  next_toward(x, y)

    Повертає число, найближче до x, у напрямку до y.

  normalize(x)

    Зводить x до найпростішої форми.

  number_class(x)

    Повертає вказівник класу x.

  plus(x)

    Плюс відповідає унарному префіксу плюс-оператор у Python. Ця операція застосовує точність контексту та округлення, тому це не операція ідентифікації.

  power(x, y, modulo=None)

    Повертає `x` до степеня `y`, зменшеного за модулем `modulo`, якщо задано.

    With two arguments, compute `x**y`. If `x` is negative then `y` must be integral. The result will be inexact unless `y` is integral and the result is finite and can be expressed exactly in „precision“ digits. The rounding mode of the context is used. Results are always correctly rounded in the Python version.

    `Decimal(0) ** Decimal(0)` призводить до `InvalidOperation`, і якщо `InvalidOperation` не перехоплюється, то призводить до `Decimal('NaN')`.

    Змінено в версії 3.3: The C module computes `power()` in terms of the correctly rounded `exp()` and `ln()` functions. The result is well-defined but only «almost always correctly rounded».

    З трьома аргументами обчисліть `(x**y) % по модулю`. Для форми з трьома аргументами діють такі обмеження на аргументи:

    - всі три аргументи повинні бути цілими

    - «y» має бути невід’ємним

    - принаймні один із `x` або `y` має бути ненульовим

    - `modulo` має бути ненульовим і мати щонайбільше цифр «точності».

    Значення, отримане за допомогою `Context.power(x, y, modulo)`, дорівнює значенню, яке було б отримано шляхом обчислення `(x**y) % по модулю` з необмеженою точністю, але обчислюється ефективніше . Показник ступеня результату дорівнює нулю, незалежно від показників `x`, `y` і `modulo`. Результат завжди точний.

  quantize(x, y)

    Повертає значення, яке дорівнює x (округлене), має експоненту y.

  radix()

    Просто повертає 10, оскільки це десяткове значення :)

  remainder(x, y)

    Повертає залишок від цілочисельного ділення.

    Знак результату, якщо він відмінний від нуля, такий самий, як у вихідного дивіденда.

  remainder_near(x, y)

    Повертає `x - y * n`, де n — це ціле число, найближче до точного значення `x / y` (якщо результат дорівнює 0, то його знаком буде знак x).

  rotate(x, y)

    Повертає повернуту копію x, y разів.

  same_quantum(x, y)

    Повертає `True`, якщо два операнди мають однаковий експонент.

  scaleb(x, y)

    Повертає перший операнд після додавання другого значення його виразу.

  shift(x, y)

    Повертає зміщену копію x, y разів.

  sqrt(x)

    Квадратний корінь із невід’ємного числа до точності контексту.

  subtract(x, y)

    Повертає різницю між x і y.

  to_eng_string(x)

    Перетворіть на рядок, використовуючи технічну нотацію, якщо потрібен експонент.

    Інженерна нотація має експоненту, кратну 3. Це може залишати до 3 цифр ліворуч від десяткового знака та може потребувати додавання одного або двох нулів у кінці.

  to_integral_exact(x)

    Округлює до цілого числа.

  to_sci_string(x)

    Перетворює число на рядок, використовуючи наукову нотацію.

## Константи

Константи в цьому розділі актуальні лише для модуля C. Вони також включені в чисту версію Python для сумісності.

| 32-розрядний | 64-розрядний
--- | --- | ---
decimal.MAX_PREC | `425000000` | `999999999999999999`
decimal.MAX_EMAX | `425000000` | `999999999999999999`
decimal.MIN_EMIN | `-425000000` | `-999999999999999999`
decimal.MIN_ETINY | `-849999999` | `-1999999999999999997`

decimal.HAVE_THREADS

  Значенням є `True`. Застаріло, оскільки Python тепер завжди має потоки.

Застаріло починаючи з версії 3.9.

decimal.HAVE_CONTEXTVAR

  Значення за замовчуванням – `True`. Якщо Python `налаштовано за допомогою параметра --without-decimal-contextvar`, версія C використовує локальний контекст потоку, а не локальний контекст співпрограми, а значенням є `False`. Це трохи швидше в деяких сценаріях вкладеного контексту.

Нове в версії 3.8.3.

## Режими округлення

decimal.ROUND_CEILING

  Round towards `Infinity`.

decimal.ROUND_DOWN

  Округлити в бік нуля.

decimal.ROUND_FLOOR

  Round towards `-Infinity`.

decimal.ROUND_HALF_DOWN

  Округліть до найближчого із рівністю до нуля.

decimal.ROUND_HALF_EVEN

  Округліть до найближчого зі зв’язками до найближчого парного цілого числа.

decimal.ROUND_HALF_UP

  Округліть до найближчого із рівнем від нуля.

decimal.ROUND_UP

  Округлити від нуля.

decimal.ROUND_05UP

  Округлити від нуля, якщо остання цифра після округлення до нуля була б 0 або 5; інакше округліть до нуля.

## Сигнали

Сигнали представляють умови, які виникають під час обчислення. Кожен відповідає одному прапорцю контексту та одному активатору перехоплення контексту.

Прапор контексту встановлюється щоразу, коли зустрічається умова. Після обчислення прапорці можуть бути перевірені в інформаційних цілях (наприклад, щоб визначити, чи було обчислення точним). Після перевірки прапорів обов’язково видаліть усі прапорці перед початком наступного обчислення.

Якщо для сигналу встановлено активатор перехоплення контексту, тоді умова викликає виняток Python. Наприклад, якщо встановлено перехоплення `DivisionByZero`, тоді виникає виняткова ситуація `DivisionByZero`, коли зустрічається умова.

class decimal.Clamped

  Змінено експоненту, щоб відповідати обмеженням представлення.

  Typically, clamping occurs when an exponent falls outside the context’s `Emin` and `Emax` limits. If possible, the exponent is reduced to fit by adding zeros to the coefficient.

class decimal.DecimalException

  Базовий клас для інших сигналів і підклас `ArithmeticError`.

class decimal.DivisionByZero

  Сигналізує про ділення нескінченного числа на нуль.

  Can occur with division, modulo division, or when raising a number to a negative power. If this signal is not trapped, returns `Infinity` or `-Infinity` with the sign determined by the inputs to the calculation.

class decimal.Inexact

  Вказує на те, що відбулося округлення і результат неточний.

  Сигнали, коли під час округлення були відкинуті ненульові цифри. Повертається округлений результат. Сигнальний прапор або пастка використовується для виявлення неточних результатів.

class decimal.InvalidOperation

  Виконано недійсну операцію.

  Indicates that an operation was requested that does not make sense. If not trapped, returns `NaN`. Possible causes include:

      Infinity - Infinity
      0 * Infinity
      Infinity / Infinity
      x % 0
      Infinity % x
      sqrt(-x) and x > 0
      0 ** 0
      x ** (non-integer)
      x ** Infinity

class decimal.Overflow

  Числове переповнення.

  Indicates the exponent is larger than `Context.Emax` after rounding has occurred. If not trapped, the result depends on the rounding mode, either pulling inward to the largest representable finite number or rounding outward to `Infinity`. In either case, `Inexact` and `Rounded` are also signaled.

class decimal.Rounded

  Відбулося округлення, хоча, можливо, жодної інформації не було втрачено.

  Signaled whenever rounding discards digits; even if those digits are zero (such as rounding `5.00` to `5.0`). If not trapped, returns the result unchanged. This signal is used to detect loss of significant digits.

class decimal.Subnormal

  Exponent was lower than `Emin` prior to rounding.

  Виникає, коли результат операції є ненормальним (експонента занадто мала). Якщо не перехоплено, повертає результат без змін.

class decimal.Underflow

  Числове недоповнення з результатом, округленим до нуля.

  Виникає, коли субнормальний результат обнулюється шляхом округлення. `Inexact` і `Subnormal` також сигналізуються.

class decimal.FloatOperation

  Увімкніть суворішу семантику для змішування чисел із плаваючою точкою та десяткових знаків.

  Якщо сигнал не перехоплюється (за замовчуванням), змішування чисел із плаваючою точкою та десяткових знаків дозволено в конструкторі `Decimal`, `create_decimal()` та в усіх операторах порівняння. І перетворення, і порівняння точні. Будь-який випадок змішаної операції автоматично записується шляхом встановлення `FloatOperation` у прапорцях контексту. Явні перетворення за допомогою `from_float()` або `create_decimal_from_float()` не встановлюють прапор.

  В іншому випадку (сигнал перехоплюється), лише порівняння рівності та явні перетворення мовчать. Усі інші змішані операції викликають `FloatOperation`.

У наступній таблиці підсумовано ієрархію сигналів:

    exceptions.ArithmeticError(exceptions.Exception)
        DecimalException
            Clamped
            DivisionByZero(DecimalException, exceptions.ZeroDivisionError)
            Inexact
                Overflow(Inexact, Rounded)
                Underflow(Inexact, Rounded, Subnormal)
            InvalidOperation
            Rounded
            Subnormal
            FloatOperation(DecimalException, exceptions.TypeError)

## Floating Point Notes

### Зменшення помилки округлення з підвищеною точністю

The use of decimal floating point eliminates decimal representation error (making it possible to represent `0.1` exactly); however, some operations can still incur round-off error when non-zero digits exceed the fixed precision.

The effects of round-off error can be amplified by the addition or subtraction of nearly offsetting quantities resulting in loss of significance. Knuth provides two instructive examples where rounded floating point arithmetic with insufficient precision causes the breakdown of the associative and distributive properties of addition:

    # Examples from Seminumerical Algorithms, Section 4.2.2.
    >>> from decimal import Decimal, getcontext
    >>> getcontext().prec = 8

    >>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
    >>> (u + v) + w
    Decimal('9.5111111')
    >>> u + (v + w)
    Decimal('10')

    >>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
    >>> (u*v) + (u*w)
    Decimal('0.01')
    >>> u * (v+w)
    Decimal('0.0060000')

Модуль `decimal` дає змогу відновити ідентифікаційні дані, збільшивши точність настільки, щоб уникнути втрати значущості:

    >>> getcontext().prec = 20
    >>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
    >>> (u + v) + w
    Decimal('9.51111111')
    >>> u + (v + w)
    Decimal('9.51111111')
    >>>
    >>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
    >>> (u*v) + (u*w)
    Decimal('0.0060000')
    >>> u * (v+w)
    Decimal('0.0060000')

### Особливі цінності

The number system for the `decimal` module provides special values including `NaN`, `sNaN`, `-Infinity`, `Infinity`, and two zeros, `+0` and `-0`.

Нескінченності можна побудувати безпосередньо за допомогою: `Decimal('Infinity')`. Крім того, вони можуть виникнути через ділення на нуль, коли сигнал `DivisionByZero` не перехоплюється. Подібним чином, коли сигнал `Overflow` не перехоплюється, нескінченність може бути результатом округлення за межі найбільшого представленого числа.

Нескінченності мають знак (афінні) і можуть використовуватися в арифметичних операціях, де вони розглядаються як дуже великі невизначені числа. Наприклад, додавання константи до нескінченності дає інший нескінченний результат.

Some operations are indeterminate and return `NaN`, or if the `InvalidOperation` signal is trapped, raise an exception. For example, `0/0` returns `NaN` which means «not a number». This variety of `NaN` is quiet and, once created, will flow through other computations always resulting in another `NaN`. This behavior can be useful for a series of computations that occasionally have missing inputs — it allows the calculation to proceed while flagging specific results as invalid.

A variant is `sNaN` which signals rather than remaining quiet after every operation. This is a useful return value when an invalid result needs to interrupt a calculation for special handling.

The behavior of Python’s comparison operators can be a little surprising where a `NaN` is involved. A test for equality where one of the operands is a quiet or signaling `NaN` always returns `False` (even when doing `Decimal('NaN')==Decimal('NaN')`), while a test for inequality always returns `True`. An attempt to compare two Decimals using any of the `<`, `<=`, `>` or `>=` operators will raise the `InvalidOperation` signal if either operand is a `NaN`, and return `False` if this signal is not trapped. Note that the General Decimal Arithmetic specification does not specify the behavior of direct comparisons; these rules for comparisons involving a `NaN` were taken from the IEEE 854 standard (see Table 3 in section 5.7). To ensure strict standards-compliance, use the `compare()` and `compare_signal()` methods instead.

Нулі зі знаком можуть виникати в результаті обчислень, які занижуються. Вони зберігають знак, який був би отриманий, якби розрахунок проводився з більшою точністю. Оскільки їх величина дорівнює нулю, додатні та від’ємні нулі вважаються рівними, а їх знак є інформаційним.

In addition to the two signed zeros which are distinct yet equal, there are various representations of zero with differing precisions yet equivalent in value. This takes a bit of getting used to. For an eye accustomed to normalized floating point representations, it is not immediately obvious that the following calculation returns a value equal to zero:

    >>> 1 / Decimal('Infinity')
    Decimal('0E-1000026')

## Робота з нитками

Функція `getcontext()` отримує доступ до іншого об’єкта `Context` для кожного потоку. Наявність окремих контекстів потоків означає, що потоки можуть вносити зміни (наприклад, `getcontext().prec=10`), не заважаючи іншим потокам.

Подібним чином функція `setcontext()` автоматично призначає свою ціль поточному потоку.

Якщо `setcontext()` не викликався раніше `getcontext()`, тоді `getcontext()` автоматично створить новий контекст для використання в поточному потоці.

Новий контекст скопійовано з контексту прототипу під назвою DefaultContext. Щоб керувати параметрами за замовчуванням, щоб кожен потік використовував однакові значення в усій програмі, безпосередньо змініть об’єкт DefaultContext. Це слід зробити перед запуском будь-яких потоків, щоб не виникало змагання між потоками, що викликають `getcontext()`. Наприклад:

    # Set applicationwide defaults for all threads about to be launched
    DefaultContext.prec = 12
    DefaultContext.rounding = ROUND_DOWN
    DefaultContext.traps = ExtendedContext.traps.copy()
    DefaultContext.traps[InvalidOperation] = 1
    setcontext(DefaultContext)

    # Afterwards, the threads can be started
    t1.start()
    t2.start()
    t3.start()
     . . .

## рецепти

Ось кілька рецептів, які служать допоміжними функціями та демонструють способи роботи з класом `Decimal`:

    def moneyfmt(value, places=2, curr='', sep=',', dp='.',
                 pos='', neg='-', trailneg=''):
        """Convert Decimal to a money formatted string.

        places:  required number of places after the decimal point
        curr:    optional currency symbol before the sign (may be blank)
        sep:     optional grouping separator (comma, period, space, or blank)
        dp:      decimal point indicator (comma or period)
                 only specify as blank when places is zero
        pos:     optional sign for positive numbers: '+', space or blank
        neg:     optional sign for negative numbers: '-', '(', space or blank
        trailneg:optional trailing minus indicator:  '-', ')', space or blank

        >>> d = Decimal('-1234567.8901')
        >>> moneyfmt(d, curr='$')
        '-$1,234,567.89'
        >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
        '1.234.568-'
        >>> moneyfmt(d, curr='$', neg='(', trailneg=')')
        '($1,234,567.89)'
        >>> moneyfmt(Decimal(123456789), sep=' ')
        '123 456 789.00'
        >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
        '<0.02>'

        """
        q = Decimal(10) ** -places      # 2 places --> '0.01'
        sign, digits, exp = value.quantize(q).as_tuple()
        result = []
        digits = list(map(str, digits))
        build, next = result.append, digits.pop
        if sign:
            build(trailneg)
        for i in range(places):
            build(next() if digits else '0')
        if places:
            build(dp)
        if not digits:
            build('0')
        i = 0
        while digits:
            build(next())
            i += 1
            if i == 3 and digits:
                i = 0
                build(sep)
        build(curr)
        build(neg if sign else pos)
        return ''.join(reversed(result))

    def pi():
        """Compute Pi to the current precision.

        >>> print(pi())
        3.141592653589793238462643383

        """
        getcontext().prec += 2  # extra digits for intermediate steps
        three = Decimal(3)      # substitute "three=3.0" for regular floats
        lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
        while s != lasts:
            lasts = s
            n, na = n+na, na+8
            d, da = d+da, da+32
            t = (t * n) / d
            s += t
        getcontext().prec -= 2
        return +s               # unary plus applies the new precision

    def exp(x):
        """Return e raised to the power of x.  Result type matches input type.

        >>> print(exp(Decimal(1)))
        2.718281828459045235360287471
        >>> print(exp(Decimal(2)))
        7.389056098930650227230427461
        >>> print(exp(2.0))
        7.38905609893
        >>> print(exp(2+0j))
        (7.38905609893+0j)

        """
        getcontext().prec += 2
        i, lasts, s, fact, num = 0, 0, 1, 1, 1
        while s != lasts:
            lasts = s
            i += 1
            fact *= i
            num *= x
            s += num / fact
        getcontext().prec -= 2
        return +s

    def cos(x):
        """Return the cosine of x as measured in radians.

        The Taylor series approximation works best for a small value of x.
        For larger values, first compute x = x % (2 * pi).

        >>> print(cos(Decimal('0.5')))
        0.8775825618903727161162815826
        >>> print(cos(0.5))
        0.87758256189
        >>> print(cos(0.5+0j))
        (0.87758256189+0j)

        """
        getcontext().prec += 2
        i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1
        while s != lasts:
            lasts = s
            i += 2
            fact *= i * (i-1)
            num *= x * x
            sign *= -1
            s += num / fact * sign
        getcontext().prec -= 2
        return +s

    def sin(x):
        """Return the sine of x as measured in radians.

        The Taylor series approximation works best for a small value of x.
        For larger values, first compute x = x % (2 * pi).

        >>> print(sin(Decimal('0.5')))
        0.4794255386042030002732879352
        >>> print(sin(0.5))
        0.479425538604
        >>> print(sin(0.5+0j))
        (0.479425538604+0j)

        """
        getcontext().prec += 2
        i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1
        while s != lasts:
            lasts = s
            i += 2
            fact *= i * (i-1)
            num *= x * x
            sign *= -1
            s += num / fact * sign
        getcontext().prec -= 2
        return +s

## Десятковий FAQ

З. Громіздко вводити `decimal.Decimal('1234.5')`. Чи є спосіб мінімізувати введення під час використання інтерактивного перекладача?

A. Деякі користувачі скорочують конструктор лише до однієї літери:

    >>> D = decimal.Decimal
    >>> D('1.23') + D('3.45')
    Decimal('4.68')

Q. У програмі з фіксованою комою з двома знаками після коми деякі вхідні дані мають багато знаків і їх потрібно округлити. Інші не повинні мати зайвих цифр і потребують перевірки. Які методи слід використовувати?

A. The `quantize()` method rounds to a fixed number of decimal places. If the `Inexact` trap is set, it is also useful for validation:

    >>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')

    >>> # Round to two places
    >>> Decimal('3.214').quantize(TWOPLACES)
    Decimal('3.21')

    >>> # Validate that a number does not exceed two places
    >>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
    Decimal('3.21')

    >>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
    Traceback (most recent call last):
       ...
    Inexact: None

З. Якщо я маю дійсні двомісні введення, як мені підтримувати цей інваріант у всій програмі?

A. Some operations like addition, subtraction, and multiplication by an integer will automatically preserve fixed point. Others operations, like division and non-integer multiplication, will change the number of decimal places and need to be followed-up with a `quantize()` step:

    >>> a = Decimal('102.72')           # Initial fixed-point values
    >>> b = Decimal('3.17')
    >>> a + b                           # Addition preserves fixed-point
    Decimal('105.89')
    >>> a - b
    Decimal('99.55')
    >>> a * 42                          # So does integer multiplication
    Decimal('4314.24')
    >>> (a * b).quantize(TWOPLACES)     # Must quantize non-integer multiplication
    Decimal('325.62')
    >>> (b / a).quantize(TWOPLACES)     # And quantize division
    Decimal('0.03')

In developing fixed-point applications, it is convenient to define functions to handle the `quantize()` step:

    >>> def mul(x, y, fp=TWOPLACES):
    ...     return (x * y).quantize(fp)
    >>> def div(x, y, fp=TWOPLACES):
    ...     return (x / y).quantize(fp)

    >>> mul(a, b)                       # Automatically preserve fixed-point
    Decimal('325.62')
    >>> div(b, a)
    Decimal('0.03')

Q. There are many ways to express the same value. The numbers `200`, `200.000`, `2E2`, and `.02E+4` all have the same value at various precisions. Is there a way to transform them to a single recognizable canonical value?

A. The `normalize()` method maps all equivalent values to a single representative:

    >>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())
    >>> [v.normalize() for v in values]
    [Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]

Q. When does rounding occur in a computation?

A. It occurs after the computation. The philosophy of the decimal specification is that numbers are considered exact and are created independent of the current context. They can even have greater precision than current context. Computations process with those exact inputs and then rounding (or other context operations) is applied to the result of the computation:

    >>> getcontext().prec = 5
    >>> pi = Decimal('3.1415926535')   # More than 5 digits
    >>> pi                             # All digits are retained
    Decimal('3.1415926535')
    >>> pi + 0                         # Rounded after an addition
    Decimal('3.1416')
    >>> pi - Decimal('0.00005')        # Subtract unrounded numbers, then round
    Decimal('3.1415')
    >>> pi + 0 - Decimal('0.00005').   # Intermediate values are rounded
    Decimal('3.1416')

З. Деякі десяткові значення завжди друкуються в експоненціальному вигляді. Чи є спосіб отримати неекспоненціальне представлення?

A. For some values, exponential notation is the only way to express the number of significant places in the coefficient. For example, expressing `5.0E+3` as `5000` keeps the value constant but cannot show the original’s two-place significance.

Якщо програма не піклується про відстеження значущості, можна легко видалити експоненту та кінцеві нулі, втрачаючи значущість, але зберігаючи значення незмінним:

    >>> def remove_exponent(d):
    ...     return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

    >>> remove_exponent(Decimal('5E+3'))
    Decimal('5000')

Q. Чи є спосіб перетворити звичайний float на `Decimal`?

A. Yes, any binary floating point number can be exactly expressed as a Decimal though an exact conversion may take more precision than intuition would suggest:

    >>> Decimal(math.pi)
    Decimal('3.141592653589793115997963468544185161590576171875')

Q. Як я можу переконатися, що в рамках складного обчислення я не отримав фальшивий результат через недостатню точність або аномалії округлення.

A. Десятковий модуль дозволяє легко перевірити результати. Найкраща практика — повторити обчислення з більшою точністю та різними режимами округлення. Різні результати вказують на недостатню точність, проблеми з режимом округлення, погано обумовлені вхідні дані або чисельно нестабільний алгоритм.

З. Я помітив, що точність контексту застосовується до результатів операцій, але не до вхідних даних. Чи є на що слід звернути увагу під час змішування значень різної точності?

А. Так. Принцип полягає в тому, що всі значення вважаються точними, як і арифметика цих значень. Округлюються лише результати. Перевага введення даних полягає в тому, що «те, що ви вводите, те й отримуєте». Недоліком є те, що результати можуть виглядати дивно, якщо ви забудете, що вхідні дані не були округлені:

    >>> getcontext().prec = 3
    >>> Decimal('3.104') + Decimal('2.104')
    Decimal('5.21')
    >>> Decimal('3.104') + Decimal('0.000') + Decimal('2.104')
    Decimal('5.20')

Рішення полягає в тому, щоб підвищити точність або примусово округлити вхідні дані за допомогою унарної операції плюс:

    >>> getcontext().prec = 3
    >>> +Decimal('1.23456789')      # unary plus triggers rounding
    Decimal('1.23')

Крім того, вхідні дані можна округлити під час створення за допомогою методу `Context.create_decimal()`:

    >>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')
    Decimal('1.2345')

Q. Чи швидка реалізація CPython для великих чисел?

A. Yes. In the CPython and PyPy3 implementations, the C/CFFI versions of the decimal module integrate the high speed libmpdec library for arbitrary precision correctly rounded decimal floating point arithmetic [1]. `libmpdec` uses Karatsuba multiplication for medium-sized numbers and the Number Theoretic Transform for very large numbers.

The context must be adapted for exact arbitrary precision arithmetic. `Emin` and `Emax` should always be set to the maximum values, `clamp` should always be 0 (the default). Setting `prec` requires some care.

The easiest approach for trying out bignum arithmetic is to use the maximum value for `prec` as well [2]:

    >>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN))
    >>> x = Decimal(2) ** 256
    >>> x / 128
    Decimal('904625697166532776746648320380374280103671755200316906558262375061821325312')

For inexact results, `MAX_PREC` is far too large on 64-bit platforms and the available memory will be insufficient:

    >>> Decimal(1) / 3
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    MemoryError

On systems with overallocation (e.g. Linux), a more sophisticated approach is to adjust `prec` to the amount of available RAM. Suppose that you have 8GB of RAM and expect 10 simultaneous operands using a maximum of 500MB each:

    >>> import sys
    >>>
    >>> # Maximum number of digits for a single operand using 500MB in 8-byte words
    >>> # with 19 digits per word (4-byte and 9 digits for the 32-bit build):
    >>> maxdigits = 19 * ((500 * 1024**2) // 8)
    >>>
    >>> # Check that this works:
    >>> c = Context(prec=maxdigits, Emax=MAX_EMAX, Emin=MIN_EMIN)
    >>> c.traps[Inexact] = True
    >>> setcontext(c)
    >>>
    >>> # Fill the available precision with nines:
    >>> x = Decimal(0).logical_invert() * 9
    >>> sys.getsizeof(x)
    524288112
    >>> x + 2
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      decimal.Inexact: [<class 'decimal.Inexact'>]

Загалом (і особливо в системах без загального розподілу) рекомендується оцінювати ще більш жорсткі межі та встановлювати пастку `Inexact`, якщо очікується, що всі обчислення будуть точними.

[1]

Нове в версії 3.3.

[2]

Змінено в версії 3.9: Цей підхід тепер працює для всіх точних результатів, за винятком нецілих степенів.