Документация Python неофициальный перевод

decimal.md

1926 строк · 95.8 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.1/library/decimal.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 9.4. `decimal` – десятичная арифметика с фиксированной и плавающей точкой89The `decimal` module provides support for decimal floating point arithmetic. It offers several advantages over the [`float`](https://python-all.ru/3.1/library/functions.html#float) datatype:1011- Decimal «основан на модели с плавающей запятой, разработанной с учетом человеческих потребностей, и имеет первостепенный руководящий принцип – компьютеры должны обеспечивать арифметику, работающую так же, как арифметика, которой люди учатся в школе». – отрывок из спецификации десятичной арифметики.12- Десятичные числа можно представить точно. В отличие от этого, числа вроде `1.1` и `2.2` не имеют точного представления в двоичной арифметике с плавающей точкой. Конечные пользователи обычно не ожидают, что `1.1 + 2.2` будет отображаться как `3.3000000000000003`, как это происходит с двоичной плавающей точкой.13- Точность сохраняется и в арифметике. В десятичной арифметике с плавающей точкой `0.1 + 0.1 + 0.1 - 0.3` точно равен нулю. В двоичной арифметике с плавающей точкой результат равен `5.5511151231257827e-017`. Хотя это значение близко к нулю, различия мешают надёжной проверке на равенство, и ошибки могут накапливаться. По этой причине десятичная арифметика предпочтительна в бухгалтерских приложениях, где требуются строгие инварианты равенства.14- Модуль decimal включает понятие значащих разрядов, так что `1.30 + 1.20` равно `2.50`. Замыкающий ноль сохраняется для указания значимости. Это стандартное представление для финансовых приложений. Для умножения «школьный» подход использует все цифры множителей. Например, `1.3 * 1.2` даёт `1.56`, а `1.30 * 1.20` даёт `1.5600`.15- В отличие от аппаратно реализованной двоичной арифметики с плавающей запятой, модуль decimal имеет настраиваемую точность (по умолчанию 28 знаков), которая может быть сколь угодно большой для данной задачи:1617  ```python18  >>> from decimal import *19  >>> getcontext().prec = 620  >>> Decimal(1) / Decimal(7)21  Decimal('0.142857')22  >>> getcontext().prec = 2823  >>> Decimal(1) / Decimal(7)24  Decimal('0.1428571428571428571428571429')25  ```26- Как двоичная, так и десятичная арифметика с плавающей запятой реализованы в соответствии с опубликованными стандартами. В то время как встроенный тип float предоставляет лишь скромную часть своих возможностей, модуль decimal предоставляет все необходимые части стандарта. При необходимости программист имеет полный контроль над округлением и обработкой сигналов. Это включает возможность принудительного точного выполнения арифметики с помощью исключений для блокировки любых неточных операций.27- Модуль decimal был разработан для поддержки «без каких-либо предпочтений как точной неокруглённой десятичной арифметики (иногда называемой арифметикой с фиксированной запятой), так и округлённой арифметики с плавающей запятой.» – выдержка из спецификации десятичной арифметики.2829Дизайн модуля сосредоточен на трёх концепциях: десятичное число, контекст арифметики и сигналы.3031Десятичное число неизменяемо. Оно имеет знак, цифры коэффициента и показатель степени. Чтобы сохранить значимость, цифры коэффициента не отбрасывают конечные нули. Десятичные числа также включают специальные значения, такие как `Infinity`, `-Infinity` и `NaN`. Стандарт также различает `-0` и `+0`.3233Контекст для арифметики – это окружение, задающее точность, правила округления, ограничения на показатели степени, флаги, указывающие на результаты операций, и включатели ловушек, которые определяют, обрабатываются ли сигналы как исключения. Варианты округления включают `ROUND_CEILING`, `ROUND_DOWN`, `ROUND_FLOOR`, `ROUND_HALF_DOWN`, `ROUND_HALF_EVEN`, `ROUND_HALF_UP`, `ROUND_UP` и `ROUND_05UP`.3435Сигналы – это группы исключительных условий, возникающих в ходе вычислений. В зависимости от потребностей приложения сигналы могут игнорироваться, рассматриваться как информационные или обрабатываться как исключения. Сигналы в модуле decimal: [`Clamped`](https://python-all.ru/3.1/library/decimal.html#decimal.Clamped), [`InvalidOperation`](https://python-all.ru/3.1/library/decimal.html#decimal.InvalidOperation), [`DivisionByZero`](https://python-all.ru/3.1/library/decimal.html#decimal.DivisionByZero), [`Inexact`](https://python-all.ru/3.1/library/decimal.html#decimal.Inexact), [`Rounded`](https://python-all.ru/3.1/library/decimal.html#decimal.Rounded), [`Subnormal`](https://python-all.ru/3.1/library/decimal.html#decimal.Subnormal), [`Overflow`](https://python-all.ru/3.1/library/decimal.html#decimal.Overflow) и [`Underflow`](https://python-all.ru/3.1/library/decimal.html#decimal.Underflow).3637Для каждого сигнала существует флаг и активатор ловушки. Когда сигнал обнаруживается, его флаг устанавливается в единицу, затем, если активатор ловушки установлен в единицу, возбуждается исключение. Флаги сохраняют состояние, поэтому пользователю необходимо сбрасывать их перед мониторингом вычислений.3839> **См. также**40>41> - Спецификация общей десятичной арифметики IBM, [Общая спецификация десятичной арифметики](https://python-all.ru/3.1/library/decimal.html).42> - Стандарт IEEE 854-1987, [Неофициальный текст IEEE 854](https://python-all.ru/3.1/library/decimal.html).4344## 9.4.1. Краткое руководство4546Обычно для работы с десятичными числами модуль импортируют, просматривают текущий контекст с помощью [`getcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.getcontext) и, при необходимости, устанавливают новые значения точности, округления или включённых ловушек:4748```python49>>> from decimal import *50>>> getcontext()51Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,52        capitals=1, flags=[], traps=[Overflow, DivisionByZero,53        InvalidOperation])5455>>> getcontext().prec = 7       # Установить новую точность56```5758Экземпляры Decimal можно создавать из целых чисел, строк или кортежей. Чтобы создать Decimal из [`float`](https://python-all.ru/3.1/library/functions.html#float), сначала преобразуйте его в строку. Это служит явным напоминанием о деталях преобразования (включая ошибку представления). Десятичные числа включают специальные значения, такие как `NaN`, что означает «Не число», положительную и отрицательную `Infinity`, а также `-0`.5960```python61>>> getcontext().prec = 2862>>> Decimal(10)63Decimal('10')64>>> Decimal('3.14')65Decimal('3.14')66>>> Decimal((0, (3, 1, 4), -2))67Decimal('3.14')68>>> Decimal(str(2.0 ** 0.5))69Decimal('1.41421356237')70>>> Decimal(2) ** Decimal('0.5')71Decimal('1.414213562373095048801688724')72>>> Decimal('NaN')73Decimal('NaN')74>>> Decimal('-Infinity')75Decimal('-Infinity')76```7778Значимость нового Decimal определяется исключительно количеством введённых цифр. Точность контекста и округление вступают в силу только во время арифметических операций.7980```python81>>> getcontext().prec = 682>>> Decimal('3.0')83Decimal('3.0')84>>> Decimal('3.1415926535')85Decimal('3.1415926535')86>>> Decimal('3.1415926535') + Decimal('2.7182818285')87Decimal('5.85987')88>>> getcontext().rounding = ROUND_UP89>>> Decimal('3.1415926535') + Decimal('2.7182818285')90Decimal('5.85988')91```9293Десятичные числа хорошо взаимодействуют с остальной частью Python. Вот небольшой пример разнообразия десятичной арифметики с плавающей точкой:9495```python96>>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))97>>> max(data)98Decimal('9.25')99>>> min(data)100Decimal('0.03')101>>> sorted(data)102[Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),103 Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]104>>> sum(data)105Decimal('19.29')106>>> a,b,c = data[:3]107>>> str(a)108'1.34'109>>> float(a)1101.34111>>> round(a, 1)112Decimal('1.3')113>>> int(a)1141115>>> a * 5116Decimal('6.70')117>>> a * b118Decimal('2.5058')119>>> c % a120Decimal('0.77')121```122123Также некоторые математические функции доступны для Decimal:124125```python126>>> getcontext().prec = 28127>>> Decimal(2).sqrt()128Decimal('1.414213562373095048801688724')129>>> Decimal(1).exp()130Decimal('2.718281828459045235360287471')131>>> Decimal('10').ln()132Decimal('2.302585092994045684017991455')133>>> Decimal('10').log10()134Decimal('1')135```136137Метод `quantize()` округляет число до заданного показателя степени. Этот метод полезен для денежных приложений, которые часто округляют результаты до фиксированного количества знаков:138139```python140>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)141Decimal('7.32')142>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)143Decimal('8')144```145146Как показано выше, функция [`getcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.getcontext) обращается к текущему контексту и позволяет изменять настройки. Такой подход удовлетворяет потребности большинства приложений.147148Для более сложной работы может быть полезно создавать альтернативные контексты с помощью конструктора Context(). Чтобы сделать альтернативный контекст активным, используйте функцию [`setcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.setcontext).149150In accordance with the standard, the `Decimal` module provides two ready to use standard contexts, [`BasicContext`](https://python-all.ru/3.1/library/decimal.html#decimal.BasicContext) and [`ExtendedContext`](https://python-all.ru/3.1/library/decimal.html#decimal.ExtendedContext). The former is especially useful for debugging because many of the traps are enabled:151152```python153>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)154>>> setcontext(myothercontext)155>>> Decimal(1) / Decimal(7)156Decimal('0.142857142857142857142857142857142857142857142857142857142857')157158>>> ExtendedContext159Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,160        capitals=1, flags=[], traps=[])161>>> setcontext(ExtendedContext)162>>> Decimal(1) / Decimal(7)163Decimal('0.142857143')164>>> Decimal(42) / Decimal(0)165Decimal('Infinity')166167>>> setcontext(BasicContext)168>>> Decimal(42) / Decimal(0)169Traceback (most recent call last):170  File "<pyshell#143>", line 1, in -toplevel-171    Decimal(42) / Decimal(0)172DivisionByZero: x / 0173```174175Контексты также имеют флаги сигналов для отслеживания исключительных ситуаций, возникающих во время вычислений. Флаги остаются установленными до явного сброса, поэтому лучше всего сбрасывать флаги перед каждой серией отслеживаемых вычислений с помощью метода `clear_flags()`.176177```python178>>> setcontext(ExtendedContext)179>>> getcontext().clear_flags()180>>> Decimal(355) / Decimal(113)181Decimal('3.14159292')182>>> getcontext()183Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,184        capitals=1, flags=[Inexact, Rounded], traps=[])185```186187Запись *flags* показывает, что рациональное приближение к `Pi` было округлено (цифры за пределами точности контекста были отброшены) и что результат неточен (некоторые отброшенные цифры были ненулевыми).188189Отдельные ловушки устанавливаются с помощью словаря в поле `traps` контекста:190191```python192>>> setcontext(ExtendedContext)193>>> Decimal(1) / Decimal(0)194Decimal('Infinity')195>>> getcontext().traps[DivisionByZero] = 1196>>> Decimal(1) / Decimal(0)197Traceback (most recent call last):198  File "<pyshell#112>", line 1, in -toplevel-199    Decimal(1) / Decimal(0)200DivisionByZero: x / 0201```202203Большинство программ настраивают текущий контекст только один раз, в начале программы. И во многих приложениях данные преобразуются в [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal) с помощью одного приведения в цикле. После установки контекста и создания десятичных чисел основная часть программы манипулирует данными точно так же, как и с другими числовыми типами Python.204205## 9.4.2. Объекты Decimal206207#### `class decimal.Decimal(value="0", context=None)`208209Создаёт новый объект [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal) на основе *value*.210211*value* может быть целым числом, строкой, кортежем или другим объектом [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal). Если *value* не указано, возвращается `Decimal('0')`. Если *value* является строкой, она должна соответствовать синтаксису десятичной числовой строки после удаления начальных и конечных пробелов:212213```python214sign           ::=  '+' | '-'215digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'216indicator      ::=  'e' | 'E'217digits         ::=  digit [digit]...218decimal-part   ::=  digits '.' [digits] | ['.'] digits219exponent-part  ::=  indicator [sign] digits220infinity       ::=  'Infinity' | 'Inf'221nan            ::=  'NaN' [digits] | 'sNaN' [digits]222numeric-value  ::=  decimal-part [exponent-part] | infinity223numeric-string ::=  [sign] numeric-value | [sign] nan224```225226Другие десятичные цифры Unicode также допускаются там, где выше указано `digit`. К ним относятся десятичные цифры из различных других алфавитов (например, арабо-индийские цифры и деванагари), а также полноширинные цифры от `'\uff10'` до `'\uff19'`.227228Если *value* является [`tuple`](https://python-all.ru/3.1/library/functions.html#tuple), он должен иметь три компонента: знак (`0` для положительного или `1` для отрицательного), [`tuple`](https://python-all.ru/3.1/library/functions.html#tuple) цифр и целочисленный показатель степени. Например, `Decimal((0, (1, 4, 1, 4), -3))` возвращает `Decimal('1.414')`.229230Точность *context* не влияет на количество сохраняемых цифр. Оно определяется исключительно количеством цифр в *value*. Например, `Decimal('3.00000')` сохраняет все пять нулей, даже если точность контекста равна только трём.231232Назначение аргумента *context* – определить, что делать, если *value* является некорректной строкой. Если контекст перехватывает сигнал [`InvalidOperation`](https://python-all.ru/3.1/library/decimal.html#decimal.InvalidOperation), вызывается исключение; в противном случае конструктор возвращает новый Decimal со значением `NaN`.233234После создания объекты [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal) являются неизменяемыми.235236Объекты Decimal имеют много общего с другими встроенными числовыми типами, такими как [`float`](https://python-all.ru/3.1/library/functions.html#float) и [`int`](https://python-all.ru/3.1/library/functions.html#int). Для них определены все стандартные математические операции и специальные методы. Кроме того, десятичные объекты можно копировать, сериализовать (pickle), выводить на печать, использовать в качестве ключей словаря, элементов множества, сравнивать, сортировать и преобразовывать в другой тип (например, [`float`](https://python-all.ru/3.1/library/functions.html#float) или [`int`](https://python-all.ru/3.1/library/functions.html#int)).237238В дополнение к стандартным числовым свойствам десятичные объекты с плавающей точкой также имеют ряд специализированных методов:239240#### `adjusted()`241242Возвращает скорректированный показатель степени после удаления крайних правых цифр коэффициента, пока не останется только старшая цифра:243244`Decimal('321e+5').adjusted()`245246возвращает семь. Используется для определения положения самой значащей цифры относительно десятичной точки.247248#### `as_tuple()`249250Возвращает представление числа в виде251252[*именованного кортежа*](https://python-all.ru/3.1/glossary.html#term-named-tuple)253254:255256`DecimalTuple(sign, digits, exponent)`257258.259260#### `canonical()`261262Возвращает каноническую кодировку аргумента. В настоящее время кодировка экземпляра263264[`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal)265266всегда канонична, поэтому эта операция возвращает свой аргумент без изменений.267268#### `compare(other[, context])`269270Сравнивает значения двух экземпляров Decimal. [`compare()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.compare) возвращает экземпляр Decimal, и если любой из операндов является NaN, то результатом будет NaN:271272```python273a or b is a NaN  ==> Decimal('NaN')274a < b            ==> Decimal('-1')275a == b           ==> Decimal('0')276a > b            ==> Decimal('1')277```278279#### `compare_signal(other[, context])`280281Эта операция идентична методу282283[`compare()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.compare)284285, за исключением того, что все NaN сигнализируют. То есть, если ни один операнд не является сигнальным NaN, то любой тихий NaN обрабатывается так, как если бы он был сигнальным NaN.286287#### `compare_total(other)`288289Сравнивает два операнда, используя их абстрактное представление, а не числовое значение. Аналогично методу [`compare()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.compare), но результат даёт полное упорядочение экземпляров [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal). Два экземпляра [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal) с одинаковым числовым значением, но разными представлениями сравниваются как неравные в этом упорядочении:290291```python292>>> Decimal('12.0').compare_total(Decimal('12'))293Decimal('-1')294```295296Тихие и сигнальные NaN также включены в полное упорядочение. Результат этой функции равен `Decimal('0')`, если оба операнда имеют одинаковое представление, `Decimal('-1')`, если первый операнд находится ниже в полном порядке, чем второй, и `Decimal('1')`, если первый операнд находится выше в полном порядке, чем второй операнд. Подробнее о полном порядке см. в спецификации.297298#### `compare_total_mag(other)`299300Сравнивает два операнда, используя их абстрактное представление, а не их значение, как в301302[`compare_total()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.compare_total)303304, но игнорируя знак каждого операнда.305306`x.compare_total_mag(y)`307308эквивалентно309310`x.copy_abs().compare_total(y.copy_abs())`311312.313314#### `conjugate()`315316Просто возвращает self; этот метод существует только для соответствия спецификации Decimal.317318#### `copy_abs()`319320Возвращает абсолютное значение аргумента. Эта операция не зависит от контекста и является тихой: флаги не изменяются и округление не выполняется.321322#### `copy_negate()`323324Возвращает отрицание аргумента. Эта операция не зависит от контекста и является тихой: флаги не изменяются и округление не выполняется.325326#### `copy_sign(other)`327328Возвращает копию первого операнда со знаком, установленным таким же, как знак второго операнда. Например:329330```python331>>> Decimal('2.3').copy_sign(Decimal('-1.5'))332Decimal('-2.3')333```334335Эта операция не зависит от контекста и является тихой: никакие флаги не изменяются и округление не выполняется.336337#### `exp([context])`338339Возвращает значение (натуральной) показательной функции `e**x` для заданного числа. Результат правильно округляется с использованием режима округления `ROUND_HALF_EVEN`.340341```python342>>> Decimal(1).exp()343Decimal('2.718281828459045235360287471')344>>> Decimal(321).exp()345Decimal('2.561702493119680037517373933E+139')346```347348#### `from_float(f)`349350Метод класса, который преобразует число с плавающей точкой в десятичное число точно.351352Примечание: *Decimal.from\_float(0.1)* не то же самое, что *Decimal('0.1')*. Поскольку 0.1 нельзя точно представить в двоичной арифметике с плавающей точкой, значение хранится как ближайшее представимое значение, равное *0x1.999999999999ap-4*. Эквивалентное десятичное значение – это *0.1000000000000000055511151231257827021181583404541015625*.353354```python355>>> Decimal.from_float(0.1)356Decimal('0.1000000000000000055511151231257827021181583404541015625')357>>> Decimal.from_float(float('nan'))358Decimal('NaN')359>>> Decimal.from_float(float('inf'))360Decimal('Infinity')361>>> Decimal.from_float(float('-inf'))362Decimal('-Infinity')363```364365Новое в версии 3.1.366367#### `fma(other, third[, context])`368369Совмещённое умножение-сложение. Возвращает self\*other+third без округления промежуточного произведения self\*other.370371```python372>>> Decimal(2).fma(3, 5)373Decimal('11')374```375376#### `is_canonical()`377378Возвращает379380[`True`](https://python-all.ru/3.1/library/constants.html#True)381382, если аргумент каноничен, и383384[`False`](https://python-all.ru/3.1/library/constants.html#False)385386в противном случае. В настоящее время экземпляр387388[`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal)389390всегда каноничен, поэтому эта операция всегда возвращает391392[`True`](https://python-all.ru/3.1/library/constants.html#True)393394.395396#### `is_finite()`397398Возвращает399400[`True`](https://python-all.ru/3.1/library/constants.html#True)401402, если аргумент является конечным числом, и403404[`False`](https://python-all.ru/3.1/library/constants.html#False)405406, если аргумент является бесконечностью или NaN.407408#### `is_infinite()`409410Возвращает411412[`True`](https://python-all.ru/3.1/library/constants.html#True)413414, если аргумент – положительная или отрицательная бесконечность, и415416[`False`](https://python-all.ru/3.1/library/constants.html#False)417418в противном случае.419420#### `is_nan()`421422Возвращает423424[`True`](https://python-all.ru/3.1/library/constants.html#True)425426, если аргумент – тихий или сигнализирующий NaN, и427428[`False`](https://python-all.ru/3.1/library/constants.html#False)429430в противном случае.431432#### `is_normal()`433434Возвращает435436[`True`](https://python-all.ru/3.1/library/constants.html#True)437438, если аргумент –439440*нормальное*441442конечное число. Возвращает443444[`False`](https://python-all.ru/3.1/library/constants.html#False)445446, если аргумент – ноль, субнормальное число, бесконечность или NaN.447448#### `is_qnan()`449450Возвращает451452[`True`](https://python-all.ru/3.1/library/constants.html#True)453454, если аргумент – тихий NaN, и455456[`False`](https://python-all.ru/3.1/library/constants.html#False)457458в противном случае.459460#### `is_signed()`461462Возвращает463464[`True`](https://python-all.ru/3.1/library/constants.html#True)465466, если аргумент имеет отрицательный знак, и467468[`False`](https://python-all.ru/3.1/library/constants.html#False)469470в противном случае. Обратите внимание, что нули и NaN могут иметь знак.471472#### `is_snan()`473474Возвращает475476[`True`](https://python-all.ru/3.1/library/constants.html#True)477478, если аргумент – сигнализирующий NaN, и479480[`False`](https://python-all.ru/3.1/library/constants.html#False)481482в противном случае.483484#### `is_subnormal()`485486Возвращает487488[`True`](https://python-all.ru/3.1/library/constants.html#True)489490, если аргумент субнормальный, и491492[`False`](https://python-all.ru/3.1/library/constants.html#False)493494в противном случае.495496#### `is_zero()`497498Возвращает499500[`True`](https://python-all.ru/3.1/library/constants.html#True)501502, если аргумент – (положительный или отрицательный) ноль, и503504[`False`](https://python-all.ru/3.1/library/constants.html#False)505506в противном случае.507508#### `ln([context])`509510Возвращает натуральный (по основанию e) логарифм операнда. Результат правильно округляется с использованием режима округления511512`ROUND_HALF_EVEN`513514.515516#### `log10([context])`517518Возвращает десятичный логарифм операнда. Результат корректно округляется с использованием режима округления519520`ROUND_HALF_EVEN`521522.523524#### `logb([context])`525526Для ненулевого числа возвращает скорректированный порядок операнда в виде экземпляра527528[`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal)529530. Если операнд – ноль, то возвращается531532`Decimal('-Infinity')`533534и поднимается флаг535536[`DivisionByZero`](https://python-all.ru/3.1/library/decimal.html#decimal.DivisionByZero)537538. Если операнд – бесконечность, то возвращается539540`Decimal('Infinity')`541542.543544#### `logical_and(other[, context])`545546[`logical_and()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.logical_and)547548– логическая операция, принимающая два549550*логических операнда*551552(см.553554[*Логические операнды*](https://python-all.ru/3.1/library/decimal.html#logical-operands-label)555556). Результатом является поразрядное557558`И`559560двух операндов.561562#### `logical_invert([context])`563564[`logical_invert()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.logical_invert)565566– логическая операция. Результатом является поразрядная инверсия операнда.567568#### `logical_or(other[, context])`569570[`logical_or()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.logical_or)571572– логическая операция, принимающая два573574*логических операнда*575576(см.577578[*Логические операнды*](https://python-all.ru/3.1/library/decimal.html#logical-operands-label)579580). Результатом является поразрядное581582`ИЛИ`583584двух операндов.585586#### `logical_xor(other[, context])`587588[`logical_xor()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.logical_xor)589590– логическая операция, принимающая два591592*логических операнда*593594(см.595596[*Логические операнды*](https://python-all.ru/3.1/library/decimal.html#logical-operands-label)597598). Результатом является поразрядное исключающее ИЛИ двух операндов.599600#### `max(other[, context])`601602Подобно603604`max(self, other)`605606, за исключением того, что правило округления контекста применяется перед возвратом, и что значения607608`NaN`609610либо сигнализируются, либо игнорируются (в зависимости от контекста и от того, являются ли они сигнализирующими или тихими).611612#### `max_mag(other[, context])`613614Похож на метод615616[`max()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.max)617618, но сравнение выполняется с использованием абсолютных значений операндов.619620#### `min(other[, context])`621622Как и623624`min(self, other)`625626, но с одним отличием: правило округления контекста применяется перед возвратом результата, а значения627628`NaN`629630либо сигнализируются, либо игнорируются (в зависимости от контекста и от того, являются ли они сигнальными или тихими).631632#### `min_mag(other[, context])`633634Похож на метод635636[`min()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.min)637638, но сравнение выполняется с использованием абсолютных значений операндов.639640#### `next_minus([context])`641642Возвращает наибольшее число, представимое в заданном контексте (или в контексте текущего потока, если контекст не задан), которое меньше заданного операнда.643644#### `next_plus([context])`645646Возвращает наименьшее число, представимое в заданном контексте (или в контексте текущего потока, если контекст не задан), которое больше заданного операнда.647648#### `next_toward(other[, context])`649650Если два операнда не равны, возвращает число, ближайшее к первому операнду в направлении второго операнда. Если оба операнда численно равны, возвращает копию первого операнда со знаком, установленным таким же, как знак второго операнда.651652#### `normalize([context])`653654Нормализует число, удаляя крайние правые конечные нули и преобразуя любой результат, равный655656`Decimal('0')`657658, в659660`Decimal('0e0')`661662. Используется для получения канонических значений членов класса эквивалентности. Например,663664`Decimal('32.100')`665666и667668`Decimal('0.321000e+2')`669670нормализуются до эквивалентного значения671672`Decimal('32.1')`673674.675676#### `number_class([context])`677678Возвращает строку, описывающую *класс* операнда. Возвращаемое значение является одной из следующих десяти строк.679680- `"-Infinity"` – указывает, что операнд является отрицательной бесконечностью.681- `"-Normal"` – указывает, что операнд является отрицательным нормальным числом.682- `"-Subnormal"` – указывает, что операнд отрицателен и является субнормальным.683- `"-Zero"` – указывает, что операнд является отрицательным нулём.684- `"+Zero"` – указывает, что операнд является положительным нулём.685- `"+Subnormal"` – указывает, что операнд положителен и является субнормальным.686- `"+Normal"` – указывает, что операнд является положительным нормальным числом.687- `"+Infinity"` – указывает, что операнд является положительной бесконечностью.688- `"NaN"` – указывает, что операнд является тихим NaN (не числом).689- `"sNaN"` – указывает, что операнд является сигнальным NaN.690691#### `quantize(exp[, rounding[, context[, watchexp]]])`692693Возвращает значение, равное первому операнду после округления и имеющее экспоненту второго операнда.694695```python696>>> Decimal('1.41421356').quantize(Decimal('1.000'))697Decimal('1.414')698```699700В отличие от других операций, если длина коэффициента после операции quantize превышает точность, то сигнализируется [`InvalidOperation`](https://python-all.ru/3.1/library/decimal.html#decimal.InvalidOperation). Это гарантирует, что при отсутствии ошибки квантованный порядок всегда равен порядку правого операнда.701702Также, в отличие от других операций, quantize никогда не сигнализирует Underflow, даже если результат субнормален и неточен.703704Если порядок второго операнда больше порядка первого, то может потребоваться округление. В этом случае режим округления определяется аргументом `rounding`, если он задан, иначе – аргументом `context`; если не задан ни один аргумент, используется режим округления контекста текущего потока.705706Если *watchexp* установлен (по умолчанию), то ошибка возвращается всякий раз, когда результирующий порядок больше `Emax` или меньше `Etiny`.707708#### `radix()`709710Возвращает711712`Decimal(10)`713714– основание системы счисления (базу), в которой класс715716[`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal)717718выполняет все свои арифметические операции. Включён для совместимости со спецификацией.719720#### `remainder_near(other[, context])`721722Вычисляет модуль как положительное или отрицательное значение в зависимости от того, что ближе к нулю. Например, `Decimal(10).remainder_near(6)` возвращает `Decimal('-2')`, что ближе к нулю, чем `Decimal('4')`.723724Если оба одинаково близки, выбранное значение будет иметь тот же знак, что и *self*.725726#### `rotate(other[, context])`727728Возвращает результат вращения цифр первого операнда на величину, заданную вторым операндом. Второй операнд должен быть целым числом в диапазоне от -precision до precision. Абсолютное значение второго операнда задаёт количество позиций для вращения. Если второй операнд положителен, вращение выполняется влево; в противном случае вращение выполняется вправо. Коэффициент первого операнда при необходимости дополняется слева нулями до длины precision. Знак и экспонента первого операнда не изменяются.729730#### `same_quantum(other[, context])`731732Проверяет, имеют ли self и other одинаковую экспоненту или оба являются733734`NaN`735736.737738#### `scaleb(other[, context])`739740Возвращает первый операнд с экспонентой, скорректированной на второй. Эквивалентно умножению первого операнда на741742`10**other`743744. Второй операнд должен быть целым числом.745746#### `shift(other[, context])`747748Возвращает результат сдвига цифр первого операнда на величину, заданную вторым операндом. Второй операнд должен быть целым числом в диапазоне от -precision до precision. Абсолютное значение второго операнда задаёт количество позиций для сдвига. Если второй операнд положителен, сдвиг выполняется влево; в противном случае сдвиг выполняется вправо. Вдвигаемые в коэффициент цифры являются нулями. Знак и экспонента первого операнда не изменяются.749750#### `sqrt([context])`751752Возвращает квадратный корень аргумента с полной точностью.753754#### `to_eng_string([context])`755756Преобразует в строку инженерного типа.757758В инженерной нотации показатель степени кратен 3, поэтому слева от десятичной запятой может быть до 3 цифр. Например, преобразует `Decimal('123E+1')` в `Decimal('1.23E+3')`759760#### `to_integral([rounding[, context]])`761762Идентичен методу763764[`to_integral_value()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.to_integral_value)765766. Имя767768`to_integral`769770сохранено для совместимости со старыми версиями.771772#### `to_integral_exact([rounding[, context]])`773774Округляет до ближайшего целого, сигнализируя775776[`Inexact`](https://python-all.ru/3.1/library/decimal.html#decimal.Inexact)777778или779780[`Rounded`](https://python-all.ru/3.1/library/decimal.html#decimal.Rounded)781782в зависимости от того, произошло ли округление. Режим округления определяется параметром783784`rounding`785786, если он задан, иначе – заданным787788`context`789790. Если ни один параметр не задан, используется режим округления текущего контекста.791792#### `to_integral_value([rounding[, context]])`793794Округляет до ближайшего целого без сигнализации795796[`Inexact`](https://python-all.ru/3.1/library/decimal.html#decimal.Inexact)797798или799800[`Rounded`](https://python-all.ru/3.1/library/decimal.html#decimal.Rounded)801802. Если задан, применяет803804*rounding*805806; в противном случае использует метод округления из предоставленного807808*context*809810или текущего контекста.811812### 9.4.2.1. Логические операнды813814Методы `logical_and()`, `logical_invert()`, `logical_or()` и `logical_xor()` ожидают, что их аргументы являются *логическими операндами*. *Логический операнд* – это экземпляр [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal), у которого экспонента и знак равны нулю, а цифры – либо `0`, либо `1`.815816## 9.4.3. Объекты контекста817818Контексты – это среды для арифметических операций. Они управляют точностью, задают правила округления, определяют, какие сигналы обрабатываются как исключения, и ограничивают диапазон для экспонент.819820Каждый поток имеет свой собственный текущий контекст, доступ к которому осуществляется или изменяется с помощью функций [`getcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.getcontext) и [`setcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.setcontext).821822#### `decimal.getcontext()`823824Возвращает текущий контекст активного потока.825826#### `decimal.setcontext(c)`827828Устанавливает текущий контекст активного потока в829830*c*831832.833834Также можно использовать оператор [`with`](https://python-all.ru/3.1/reference/compound_stmts.html#with) и функцию [`localcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.localcontext) для временного изменения активного контекста.835836#### `decimal.localcontext([c])`837838Возвращает менеджер контекста, который устанавливает текущий контекст для активного потока в копию *c* при входе в оператор with и восстанавливает предыдущий контекст при выходе из оператора with. Если контекст не указан, используется копия текущего контекста.839840Например, следующий код устанавливает текущую точность десятичных чисел в 42 знака, выполняет вычисление и затем автоматически восстанавливает предыдущий контекст:841842```python843from decimal import localcontext844845with localcontext() as ctx:846    ctx.prec = 42   # Выполнить вычисление с высокой точностью847    s = calculate_something()848s = +s  # Округлить конечный результат до стандартной точности849```850851Новые контексты также можно создавать с помощью конструктора [`Context`](https://python-all.ru/3.1/library/decimal.html#decimal.Context), описанного ниже. Кроме того, модуль предоставляет три готовых контекста:852853#### `class decimal.BasicContext`854855Это стандартный контекст, определённый в спецификации General Decimal Arithmetic. Точность установлена в девять. Округление установлено в `ROUND_HALF_UP`. Все флаги сброшены. Все ловушки включены (обрабатываются как исключения), за исключением [`Inexact`](https://python-all.ru/3.1/library/decimal.html#decimal.Inexact), [`Rounded`](https://python-all.ru/3.1/library/decimal.html#decimal.Rounded) и [`Subnormal`](https://python-all.ru/3.1/library/decimal.html#decimal.Subnormal).856857Поскольку многие ловушки включены, этот контекст полезен для отладки.858859#### `class decimal.ExtendedContext`860861Это стандартный контекст, определённый в спецификации General Decimal Arithmetic. Точность установлена в девять. Округление установлено в `ROUND_HALF_EVEN`. Все флаги сброшены. Ловушки не включены (так что исключения не возбуждаются при вычислениях).862863Поскольку ловушки отключены, этот контекст полезен для приложений, которые предпочитают получать значение `NaN` или `Infinity` вместо вызова исключений. Это позволяет приложению завершить выполнение при наличии условий, которые в противном случае остановили бы программу.864865#### `class decimal.DefaultContext`866867Этот контекст используется конструктором [`Context`](https://python-all.ru/3.1/library/decimal.html#decimal.Context) в качестве прототипа для новых контекстов. Изменение поля (например, точности) меняет значение по умолчанию для новых контекстов, создаваемых конструктором [`Context`](https://python-all.ru/3.1/library/decimal.html#decimal.Context).868869Этот контекст наиболее полезен в многопоточных средах. Изменение одного из полей до запуска потоков приводит к установке общесистемных значений по умолчанию. Изменять поля после запуска потоков не рекомендуется, так как это потребовало бы синхронизации потоков для предотвращения состояний гонки.870871В однопоточных средах лучше вообще не использовать этот контекст. Вместо этого просто создавайте контексты явно, как описано ниже.872873Значения по умолчанию: precision=28, rounding=ROUND\_HALF\_EVEN, включены ловушки для Overflow, InvalidOperation и DivisionByZero.874875В дополнение к трём предоставленным контекстам новые контексты можно создавать с помощью конструктора [`Context`](https://python-all.ru/3.1/library/decimal.html#decimal.Context).876877#### `class decimal.Context(prec=None, rounding=None, traps=None, flags=None, Emin=None, Emax=None, capitals=1)`878879Создаёт новый контекст. Если поле не указано или равно [`None`](https://python-all.ru/3.1/library/constants.html#None), значения по умолчанию копируются из [`DefaultContext`](https://python-all.ru/3.1/library/decimal.html#decimal.DefaultContext). Если поле *flags* не указано или равно [`None`](https://python-all.ru/3.1/library/constants.html#None), все флаги сбрасываются.880881Поле *prec* – это положительное целое число, которое задаёт точность арифметических операций в контексте.882883Параметр *rounding* может принимать одно из следующих значений:884885- `ROUND_CEILING` (в сторону `Infinity`),886- `ROUND_DOWN` (в сторону нуля),887- `ROUND_FLOOR` (в сторону `-Infinity`),888- `ROUND_HALF_DOWN` (к ближайшему, при равенстве – в сторону нуля),889- `ROUND_HALF_EVEN` (к ближайшему, при равенстве – к ближайшему чётному целому),890- `ROUND_HALF_UP` (к ближайшему, при равенстве – от нуля), или891- `ROUND_UP` (от нуля).892- `ROUND_05UP` (от нуля, если последняя цифра после округления в сторону нуля была бы 0 или 5; в противном случае – к нулю)893894Поля *traps* и *flags* содержат список сигналов, которые необходимо установить. Как правило, для новых контекстов следует задавать только ловушки (traps), а флаги (flags) оставлять сброшенными.895896Поля *Emin* и *Emax* – это целые числа, задающие допустимые внешние границы для показателей степени.897898Поле *capitals* может быть равно `0` или `1` (по умолчанию). Если установлено в `1`, показатели степени выводятся с заглавной `E`; в противном случае используется строчная `e`: `Decimal('6.02e+23')`.899900Класс [`Context`](https://python-all.ru/3.1/library/decimal.html#decimal.Context) определяет несколько методов общего назначения, а также большое количество методов для выполнения арифметических операций непосредственно в заданном контексте. Кроме того, для каждого из описанных выше методов [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal) (за исключением методов `adjusted()` и `as_tuple()`) существует соответствующий метод [`Context`](https://python-all.ru/3.1/library/decimal.html#decimal.Context). Например, `C.exp(x)` эквивалентно `x.exp(context=C)`.901902#### `clear_flags()`903904Сбрасывает все флаги в905906`0`907908.909910#### `copy()`911912Возвращает копию контекста.913914#### `copy_decimal(num)`915916Возвращает копию экземпляра Decimal num.917918#### `create_decimal(num)`919920Создаёт новый экземпляр Decimal из *num*, используя *self* в качестве контекста. В отличие от конструктора [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal), при преобразовании применяются точность контекста, метод округления, флаги и ловушки.921922Это полезно, поскольку константы часто задаются с большей точностью, чем требуется приложению. Ещё одно преимущество в том, что округление немедленно устраняет нежелательные эффекты от цифр за пределами текущей точности. В следующем примере использование неокруглённых входных данных означает, что добавление нуля к сумме может изменить результат:923924```python925>>> getcontext().prec = 3926>>> Decimal('3.4445') + Decimal('1.0023')927Decimal('4.45')928>>> Decimal('3.4445') + Decimal(0) + Decimal('1.0023')929Decimal('4.44')930```931932Этот метод реализует операцию преобразования в число из спецификации IBM. Если аргумент – строка, начальные и конечные пробелы не допускаются.933934#### `create_decimal_from_float(f)`935936Создаёт новый экземпляр Decimal из числа с плавающей запятой *f*, выполняя округление с использованием *self* в качестве контекста. В отличие от метода класса [`Decimal.from_float()`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal.from_float), при преобразовании применяются точность контекста, метод округления, флаги и ловушки.937938```python939>>> context = Context(prec=5, rounding=ROUND_DOWN)940>>> context.create_decimal_from_float(math.pi)941Decimal('3.1415')942>>> context = Context(prec=5, traps=[Inexact])943>>> context.create_decimal_from_float(math.pi)944Traceback (most recent call last):945    ...946decimal.Inexact: None947```948949Новое в версии 3.1.950951#### `Etiny()`952953Возвращает значение, равное954955`Emin - prec + 1`956957, которое является минимальным значением показателя степени для субнормальных результатов. В случае антипереполнения (underflow) показатель степени устанавливается равным958959[`Etiny`](https://python-all.ru/3.1/library/decimal.html#decimal.Context.Etiny)960961.962963#### `Etop()`964965Возвращает значение, равное966967`Emax - prec + 1`968969.970971Обычный подход к работе с десятичными числами – создавать экземпляры [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal), а затем применять арифметические операции, которые выполняются в текущем контексте активного потока. Альтернативный подход – использовать методы контекста для вычислений в заданном контексте. Эти методы аналогичны методам класса [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal) и здесь лишь кратко перечислены.972973#### `abs(x)`974975Возвращает абсолютное значение976977*x*978979.980981#### `add(x, y)`982983Возвращает сумму984985*x*986987и988989*y*990991.992993#### `canonical(x)`994995Возвращает тот же объект Decimal996997*x*998999.10001001#### `compare(x, y)`10021003Сравнивает10041005*x*10061007и10081009*y*10101011численно.10121013#### `compare_signal(x, y)`10141015Сравнивает значения двух операндов численно.10161017#### `compare_total(x, y)`10181019Сравнивает два операнда по их абстрактному представлению.10201021#### `compare_total_mag(x, y)`10221023Сравнивает два операнда по их абстрактному представлению, игнорируя знак.10241025#### `copy_abs(x)`10261027Возвращает копию10281029*x*10301031с установленным в 0 знаком.10321033#### `copy_negate(x)`10341035Возвращает копию10361037*x*10381039с инвертированным знаком.10401041#### `copy_sign(x, y)`10421043Копирует знак из10441045*y*10461047в10481049*x*10501051.10521053#### `divide(x, y)`10541055Возвращает10561057*x*10581059, делённое на10601061*y*10621063.10641065#### `divide_int(x, y)`10661067Возвращает10681069*x*10701071, делённое на10721073*y*10741075, с усечением до целого.10761077#### `divmod(x, y)`10781079Делит два числа и возвращает целую часть результата.10801081#### `exp(x)`10821083Возвращает10841085*e \*\* x*10861087.10881089#### `fma(x, y, z)`10901091Возвращает10921093*x*10941095, умноженное на10961097*y*10981099, плюс11001101*z*11021103.11041105#### `is_canonical(x)`11061107Возвращает True, если11081109*x*11101111– каноническое число; иначе False.11121113#### `is_finite(x)`11141115Возвращает True, если11161117*x*11181119– конечное число; иначе False.11201121#### `is_infinite(x)`11221123Возвращает True, если11241125*x*11261127– бесконечность; иначе False.11281129#### `is_nan(x)`11301131Возвращает True, если11321133*x*11341135– qNaN или sNaN; иначе False.11361137#### `is_normal(x)`11381139Возвращает True, если11401141*x*11421143– нормальное число; иначе False.11441145#### `is_qnan(x)`11461147Возвращает True, если11481149*x*11501151– тихий NaN; иначе False.11521153#### `is_signed(x)`11541155Возвращает True, если11561157*x*11581159– отрицательное число; иначе False.11601161#### `is_snan(x)`11621163Возвращает True, если11641165*x*11661167– сигнальный NaN; иначе False.11681169#### `is_subnormal(x)`11701171Возвращает True, если11721173*x*11741175– субнормальное число; иначе возвращает False.11761177#### `is_zero(x)`11781179Возвращает True, если11801181*x*11821183– ноль; иначе возвращает False.11841185#### `ln(x)`11861187Возвращает натуральный (по основанию e) логарифм11881189*x*11901191.11921193#### `log10(x)`11941195Возвращает десятичный логарифм11961197*x*11981199.12001201#### `logb(x)`12021203Возвращает показатель степени величины старшего разряда операнда.12041205#### `logical_and(x, y)`12061207Применяет логическую операцию12081209*and*12101211к соответствующим цифрам операндов.12121213#### `logical_invert(x)`12141215Инвертирует все цифры в12161217*x*12181219.12201221#### `logical_or(x, y)`12221223Применяет логическую операцию12241225*or*12261227к соответствующим цифрам операндов.12281229#### `logical_xor(x, y)`12301231Применяет логическую операцию12321233*xor*12341235к соответствующим цифрам операндов.12361237#### `max(x, y)`12381239Сравнивает два числа и возвращает наибольшее.12401241#### `max_mag(x, y)`12421243Сравнивает числа по модулю (игнорируя знак).12441245#### `min(x, y)`12461247Сравнивает два числа и возвращает наименьшее.12481249#### `min_mag(x, y)`12501251Сравнивает числа по модулю (игнорируя знак).12521253#### `minus(x)`12541255Минус соответствует унарному префиксному оператору минус в Python.12561257#### `multiply(x, y)`12581259Возвращает произведение12601261*x*12621263и12641265*y*12661267.12681269#### `next_minus(x)`12701271Возвращает наибольшее представимое число, меньшее чем12721273*x*12741275.12761277#### `next_plus(x)`12781279Возвращает наименьшее представимое число, большее чем12801281*x*12821283.12841285#### `next_toward(x, y)`12861287Возвращает число, ближайшее к12881289*x*12901291в направлении к12921293*y*12941295.12961297#### `normalize(x)`12981299Приводит13001301*x*13021303к простейшей форме.13041305#### `number_class(x)`13061307Возвращает указание на класс13081309*x*13101311.13121313#### `plus(x)`13141315Plus соответствует унарному префиксному оператору плюс в Python. Эта операция применяет точность и округление контекста, поэтому она13161317*не*13181319является тождественной операцией.13201321#### `power(x, y[, modulo])`13221323Возвращает `x`, возведённое в степень `y`, с приведением по модулю `modulo`, если он задан.13241325С двумя аргументами вычисляет `x**y`. Если `x` отрицательно, то `y` должно быть целым. Результат будет неточным, если только `y` не является целым и результат конечен и может быть точно выражен в цифрах 'precision'. Результат всегда должен быть правильно округлён в соответствии с режимом округления контекста текущего потока.13261327С тремя аргументами вычисляется `(x**y) % modulo`. Для формы с тремя аргументами действуют следующие ограничения:13281329> - все три аргумента должны быть целыми1330> - `y` должно быть неотрицательным1331> - по крайней мере одно из `x` или `y` должно быть ненулевым1332> - `modulo` должно быть ненулевым и содержать не более 'precision' цифр13331334Значение, полученное из `Context.power(x, y, modulo)`, равно значению, которое было бы получено при вычислении `(x**y) % modulo` с неограниченной точностью, но вычисляется более эффективно. Экспонента результата равна нулю независимо от экспонент `x`, `y` и `modulo`. Результат всегда точен.13351336#### `quantize(x, y)`13371338Возвращает значение, равное13391340*x*13411342(с округлением), с экспонентой13431344*y*13451346.13471348#### `radix()`13491350Просто возвращает 10, так как это Decimal, :)13511352#### `remainder(x, y)`13531354Возвращает остаток от целочисленного деления.13551356Знак результата, если он не равен нулю, совпадает со знаком исходного делимого.13571358#### `remainder_near(x, y)`13591360Возвращает13611362`x - y * n`13631364, где13651366*n*13671368– целое число, ближайшее к точному значению13691370`x / y`13711372(если результат равен 0, его знак будет знаком13731374*x*13751376).13771378#### `rotate(x, y)`13791380Возвращает циклически сдвинутую копию13811382*x*13831384на13851386*y*13871388раз.13891390#### `same_quantum(x, y)`13911392Возвращает True, если два операнда имеют одинаковую экспоненту.13931394#### `scaleb(x, y)`13951396Возвращает первый операнд после добавления второго значения к его экспоненте.13971398#### `shift(x, y)`13991400Возвращает сдвинутую копию14011402*x*14031404на14051406*y*14071408раз.14091410#### `sqrt(x)`14111412Квадратный корень неотрицательного числа с точностью контекста.14131414#### `subtract(x, y)`14151416Возвращает разность14171418*x*14191420и14211422*y*14231424.14251426#### `to_eng_string(x)`14271428Преобразует число в строку, используя научную нотацию.14291430#### `to_integral_exact(x)`14311432Округляет до целого.14331434#### `to_sci_string(x)`14351436Преобразует число в строку, используя научную запись.14371438## 9.4.4. Сигналы14391440Сигналы представляют условия, возникающие во время вычислений. Каждый соответствует одному флагу контекста и одному включателю ловушки контекста.14411442Флаг контекста устанавливается при возникновении условия. После вычисления флаги могут быть проверены в информационных целях (например, чтобы определить, было ли вычисление точным). После проверки флагов необходимо очистить все флаги перед началом следующего вычисления.14431444Если для сигнала включён ловушечный переключатель контекста, то условие вызывает возбуждение исключения Python. Например, если установлена ловушка [`DivisionByZero`](https://python-all.ru/3.1/library/decimal.html#decimal.DivisionByZero), то при возникновении условия возбуждается исключение [`DivisionByZero`](https://python-all.ru/3.1/library/decimal.html#decimal.DivisionByZero).14451446#### `class decimal.Clamped`14471448Изменён показатель степени для соответствия ограничениям представления.14491450Обычно усечение (clamping) происходит, когда показатель степени выходит за пределы контекста `Emin` и `Emax`. Если возможно, показатель уменьшается до допустимого значения путём добавления нулей к коэффициенту.14511452#### `class decimal.DecimalException`14531454Базовый класс для остальных сигналов и подкласс14551456[`ArithmeticError`](https://python-all.ru/3.1/library/exceptions.html#ArithmeticError)14571458.14591460#### `class decimal.DivisionByZero`14611462Сигнализирует о делении небесконечного числа на ноль.14631464Может возникнуть при делении, делении по модулю или возведении числа в отрицательную степень. Если эта ловушка не включена, возвращается `Infinity` или `-Infinity`, знак определяется входными данными вычисления.14651466#### `class decimal.Inexact`14671468Указывает, что произошло округление и результат не является точным.14691470Сигнализирует, когда при округлении были отброшены ненулевые цифры. Возвращается округлённый результат. Флаг сигнала или ловушка используется для обнаружения неточных результатов.14711472#### `class decimal.InvalidOperation`14731474Выполнена недопустимая операция.14751476Указывает на то, что была запрошена бессмысленная операция. Если ловушка не включена, возвращается `NaN`. Возможные причины включают:14771478```python1479Infinity - Infinity14800 * Infinity1481Infinity / Infinity1482x % 01483Infinity % x1484x._rescale( non-integer )1485sqrt(-x) and x > 014860 ** 01487x ** (non-integer)1488x ** Infinity1489```14901491#### `class decimal.Overflow`14921493Числовое переполнение.14941495Указывает, что показатель степени превышает `Emax` после округления. Если ловушка не включена, результат зависит от режима округления: либо округление внутрь до наибольшего представимого конечного числа, либо округление наружу до `Infinity`. В любом случае также сигнализируются [`Inexact`](https://python-all.ru/3.1/library/decimal.html#decimal.Inexact) и [`Rounded`](https://python-all.ru/3.1/library/decimal.html#decimal.Rounded).14961497#### `class decimal.Rounded`14981499Произошло округление, хотя, возможно, информация не была потеряна.15001501Срабатывает при каждом округлении, отбрасывающем цифры, даже если эти цифры нулевые (например, при округлении `5.00` до `5.0`). Если не перехвачено, возвращает результат без изменений. Этот сигнал используется для обнаружения потери значащих цифр.15021503#### `class decimal.Subnormal`15041505Exponent was lower than `Emin` prior to rounding.15061507Возникает, когда результат операции является субнормальным (экспонента слишком мала). Если не перехвачено, возвращает результат без изменений.15081509#### `class decimal.Underflow`15101511Числовое исчерпание с округлением результата до нуля.15121513Occurs when a subnormal result is pushed to zero by rounding. [`Inexact`](https://python-all.ru/3.1/library/decimal.html#decimal.Inexact) and [`Subnormal`](https://python-all.ru/3.1/library/decimal.html#decimal.Subnormal) are also signaled.15141515В следующей таблице приведена иерархия сигналов:15161517```python1518exceptions.ArithmeticError(exceptions.Exception)1519    DecimalException1520        Clamped1521        DivisionByZero(DecimalException, exceptions.ZeroDivisionError)1522        Inexact1523            Overflow(Inexact, Rounded)1524            Underflow(Inexact, Rounded, Subnormal)1525        InvalidOperation1526        Rounded1527        Subnormal1528```15291530## 9.4.5. Примечания по числам с плавающей запятой15311532### 9.4.5.1. Смягчение ошибки округления за счет увеличения точности15331534Использование десятичной арифметики с плавающей запятой устраняет ошибку десятичного представления (позволяя точно представить `0.1`); однако некоторые операции всё ещё могут приводить к ошибке округления, когда ненулевые цифры превышают фиксированную точность.15351536Влияние ошибки округления может усиливаться при сложении или вычитании почти компенсирующих друг друга величин, что приводит к потере значимости. Кнут приводит два поучительных примера, в которых округлённая арифметика с плавающей точкой с недостаточной точностью приводит к нарушению ассоциативного и дистрибутивного свойств сложения:15371538```python1539# Примеры из Seminumerical Algorithms, раздел 4.2.2.1540>>> from decimal import Decimal, getcontext1541>>> getcontext().prec = 815421543>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')1544>>> (u + v) + w1545Decimal('9.5111111')1546>>> u + (v + w)1547Decimal('10')15481549>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')1550>>> (u*v) + (u*w)1551Decimal('0.01')1552>>> u * (v+w)1553Decimal('0.0060000')1554```15551556Модуль `decimal` позволяет восстановить тождества, увеличив точность до такой степени, чтобы избежать потери значимости:15571558```python1559>>> getcontext().prec = 201560>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')1561>>> (u + v) + w1562Decimal('9.51111111')1563>>> u + (v + w)1564Decimal('9.51111111')1565>>>1566>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')1567>>> (u*v) + (u*w)1568Decimal('0.0060000')1569>>> u * (v+w)1570Decimal('0.0060000')1571```15721573### 9.4.5.2. Специальные значения15741575Система чисел модуля `decimal` предоставляет специальные значения, включая `NaN`, `sNaN`, `-Infinity`, `Infinity`, а также два нуля: `+0` и `-0`.15761577Infinities can be constructed directly with: `Decimal('Infinity')`. Also, they can arise from dividing by zero when the [`DivisionByZero`](https://python-all.ru/3.1/library/decimal.html#decimal.DivisionByZero) signal is not trapped. Likewise, when the [`Overflow`](https://python-all.ru/3.1/library/decimal.html#decimal.Overflow) signal is not trapped, infinity can result from rounding beyond the limits of the largest representable number.15781579Бесконечности являются знаковыми (аффинными) и могут использоваться в арифметических операциях, где они трактуются как очень большие неопределённые числа. Например, прибавление константы к бесконечности даёт другой бесконечный результат.15801581Some operations are indeterminate and return `NaN`, or if the [`InvalidOperation`](https://python-all.ru/3.1/library/decimal.html#decimal.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.15821583A 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.15841585The 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`](https://python-all.ru/3.1/library/constants.html#False) (even when doing `Decimal('NaN')==Decimal('NaN')`), while a test for inequality always returns [`True`](https://python-all.ru/3.1/library/constants.html#True). An attempt to compare two Decimals using any of the `<`, `<=`, `>` or `>=` operators will raise the [`InvalidOperation`](https://python-all.ru/3.1/library/decimal.html#decimal.InvalidOperation) signal if either operand is a `NaN`, and return [`False`](https://python-all.ru/3.1/library/constants.html#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.15861587Знаковые нули могут возникать в результате вычислений, приводящих к исчерпанию. Они сохраняют знак, который получился бы, если бы вычисления выполнялись с большей точностью. Поскольку их величина равна нулю, положительный и отрицательный нули считаются равными, а их знак является информационным.15881589Помимо двух знаковых нулей, которые различны, но равны, существуют различные представления нуля с разной точностью, но эквивалентные по значению. К этому нужно немного привыкнуть. Для глаза, привыкшего к нормализованным представлениям чисел с плавающей точкой, не сразу очевидно, что следующее вычисление возвращает значение, равное нулю:15901591```python1592>>> 1 / Decimal('Infinity')1593Decimal('0E-1000000026')1594```15951596## 9.4.6. Работа с потоками15971598Функция [`getcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.getcontext) обращается к другому объекту [`Context`](https://python-all.ru/3.1/library/decimal.html#decimal.Context) для\\nкаждого потока. Наличие отдельных контекстов для потоков означает, что потоки могут вносить\\nизменения (например, `getcontext.prec=10`) без помех для других потоков.15991600Likewise, the [`setcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.setcontext) function automatically assigns its target to the current thread.16011602If [`setcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.setcontext) has not been called before [`getcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.getcontext), then [`getcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.getcontext) will automatically create a new context for use in the current thread.16031604The new context is copied from a prototype context called *DefaultContext*. To control the defaults so that each thread will use the same values throughout the application, directly modify the *DefaultContext* object. This should be done *before* any threads are started so that there won’t be a race condition between threads calling [`getcontext()`](https://python-all.ru/3.1/library/decimal.html#decimal.getcontext). For example:16051606```python1607# Установить глобальные настройки по умолчанию для всех потоков, которые будут запущены1608DefaultContext.prec = 121609DefaultContext.rounding = ROUND_DOWN1610DefaultContext.traps = ExtendedContext.traps.copy()1611DefaultContext.traps[InvalidOperation] = 11612setcontext(DefaultContext)16131614# После этого потоки можно запускать1615t1.start()1616t2.start()1617t3.start()1618 . . .1619```16201621## 9.4.7. Рецепты16221623Here are a few recipes that serve as utility functions and that demonstrate ways to work with the [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal) class:16241625```python1626def moneyfmt(value, places=2, curr='', sep=',', dp='.',1627             pos='', neg='-', trailneg=''):1628    """Преобразовать Decimal в строку, отформатированную как денежная сумма.16291630    places:  обязательное количество знаков после десятичной точки1631    curr:    необязательный символ валюты перед знаком (может быть пустым)1632    sep:     необязательный разделитель групп (запятая, точка, пробел или пусто)1633    dp:      указатель десятичной точки (запятая или точка)1634             указывать пустым только при places=01635    pos:     необязательный знак для положительных чисел: '+', пробел или пусто1636    neg:     необязательный знак для отрицательных чисел: '-', '(', пробел или пусто1637    trailneg:необязательный завершающий знак минуса: '-', ')', пробел или пусто16381639    >>> d = Decimal('-1234567.8901')1640    >>> moneyfmt(d, curr='$')1641    '-$1,234,567.89'1642    >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')1643    '1.234.568-'1644    >>> moneyfmt(d, curr='$', neg='(', trailneg=')')1645    '($1,234,567.89)'1646    >>> moneyfmt(Decimal(123456789), sep=' ')1647    '123 456 789.00'1648    >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')1649    '<0.02>'16501651    """1652    q = Decimal(10) ** -places      # 2 знака после запятой --> '0.01'1653    sign, digits, exp = value.quantize(q).as_tuple()1654    result = []1655    digits = list(map(str, digits))1656    build, next = result.append, digits.pop1657    if sign:1658        build(trailneg)1659    for i in range(places):1660        build(next() if digits else '0')1661    build(dp)1662    if not digits:1663        build('0')1664    i = 01665    while digits:1666        build(next())1667        i += 11668        if i == 3 and digits:1669            i = 01670            build(sep)1671    build(curr)1672    build(neg if sign else pos)1673    return ''.join(reversed(result))16741675def pi():1676    """Вычислить число Пи с текущей точностью.16771678    >>> print(pi())1679    3.14159265358979323846264338316801681    """1682    getcontext().prec += 2  # дополнительные цифры для промежуточных шагов1683    three = Decimal(3)      # подставить "three=3.0" вместо обычных чисел с плавающей точкой1684    lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 241685    while s != lasts:1686        lasts = s1687        n, na = n+na, na+81688        d, da = d+da, da+321689        t = (t * n) / d1690        s += t1691    getcontext().prec -= 21692    return +s               # унарный плюс применяет новую точность16931694def exp(x):1695    """Возвращает e, возведённое в степень x. Тип результата соответствует типу входного значения.16961697    >>> print(exp(Decimal(1)))1698    2.7182818284590452353602874711699    >>> print(exp(Decimal(2)))1700    7.3890560989306502272304274611701    >>> print(exp(2.0))1702    7.389056098931703    >>> print(exp(2+0j))1704    (7.38905609893+0j)17051706    """1707    getcontext().prec += 21708    i, lasts, s, fact, num = 0, 0, 1, 1, 11709    while s != lasts:1710        lasts = s1711        i += 11712        fact *= i1713        num *= x1714        s += num / fact1715    getcontext().prec -= 21716    return +s17171718def cos(x):1719    """Возвращает косинус x, измеренного в радианах.17201721    >>> print(cos(Decimal('0.5')))1722    0.87758256189037271611628158261723    >>> print(cos(0.5))1724    0.877582561891725    >>> print(cos(0.5+0j))1726    (0.87758256189+0j)17271728    """1729    getcontext().prec += 21730    i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 11731    while s != lasts:1732        lasts = s1733        i += 21734        fact *= i * (i-1)1735        num *= x * x1736        sign *= -11737        s += num / fact * sign1738    getcontext().prec -= 21739    return +s17401741def sin(x):1742    """Возвращает синус угла x, заданного в радианах.17431744    >>> print(sin(Decimal('0.5')))1745    0.47942553860420300027328793521746    >>> print(sin(0.5))1747    0.4794255386041748    >>> print(sin(0.5+0j))1749    (0.479425538604+0j)17501751    """1752    getcontext().prec += 21753    i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 11754    while s != lasts:1755        lasts = s1756        i += 21757        fact *= i * (i-1)1758        num *= x * x1759        sign *= -11760        s += num / fact * sign1761    getcontext().prec -= 21762    return +s1763```17641765## 9.4.8. Часто задаваемые вопросы по decimal17661767Q. It is cumbersome to type `decimal.Decimal('1234.5')`. Is there a way to minimize typing when using the interactive interpreter?17681769Ответ. Некоторые пользователи сокращают конструктор до одной буквы:17701771```python1772>>> D = decimal.Decimal1773>>> D('1.23') + D('3.45')1774Decimal('4.68')1775```17761777Вопрос. В приложении с фиксированной запятой с двумя десятичными знаками некоторые входные данные имеют много знаков и нуждаются в округлении. Другие не должны содержать лишних цифр и требуют проверки. Какие методы следует использовать?17781779A. The `quantize()` method rounds to a fixed number of decimal places. If the [`Inexact`](https://python-all.ru/3.1/library/decimal.html#decimal.Inexact) trap is set, it is also useful for validation:17801781> ```python1782> >>> TWOPLACES = Decimal(10) ** -2       # то же, что Decimal('0.01')1783> ```1784>1785> ```python1786> >>> # Округлить до двух знаков1787> >>> Decimal('3.214').quantize(TWOPLACES)1788> Decimal('3.21')1789> ```1790>1791> ```python1792> >>> # Проверка, что число не выходит за пределы двух знаков1793> >>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))1794> Decimal('3.21')1795> ```1796>1797> ```python1798> >>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))1799> Traceback (most recent call last):1800>    ...1801> Inexact: None1802> ```18031804Вопрос. Получив корректные входные данные с двумя знаками, как поддерживать этот инвариант во всём приложении?18051806A. 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:18071808```python1809>>> a = Decimal('102.72')           # Начальные значения чисел с фиксированной точкой1810>>> b = Decimal('3.17')1811>>> a + b                           # Сложение сохраняет фиксированную точку1812Decimal('105.89')1813>>> a - b1814Decimal('99.55')1815>>> a * 42                          # Умножение на целое число – тоже1816Decimal('4314.24')1817>>> (a * b).quantize(TWOPLACES)     # Результат умножения на нецелое число нужно квантовать1818Decimal('325.62')1819>>> (b / a).quantize(TWOPLACES)     # И квантовать результат деления1820Decimal('0.03')1821```18221823In developing fixed-point applications, it is convenient to define functions to handle the `quantize()` step:18241825> ```python1826> >>> def mul(x, y, fp=TWOPLACES):1827> ...     return (x * y).quantize(fp)1828> >>> def div(x, y, fp=TWOPLACES):1829> ...     return (x / y).quantize(fp)1830> ```1831>1832> ```python1833> >>> mul(a, b)                       # Автоматически сохранять фиксированную точку1834> Decimal('325.62')1835> >>> div(b, a)1836> Decimal('0.03')1837> ```18381839Q. 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?18401841A. The `normalize()` method maps all equivalent values to a single representative:18421843```python1844>>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())1845>>> [v.normalize() for v in values]1846[Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]1847```18481849Вопрос. Некоторые значения decimal всегда выводятся в экспоненциальной записи. Есть ли способ получить неэкспоненциальное представление?18501851A. 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.18521853Если приложению не важно отслеживать значимость, можно легко удалить экспоненту и хвостовые нули, потеряв значимость, но сохранив значение:18541855> ```python1856> >>> def remove_exponent(d):1857> ...     return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()1858> ```1859>1860> ```python1861> >>> remove_exponent(Decimal('5E+3'))1862> Decimal('5000')1863> ```18641865Q. Is there a way to convert a regular float to a [`Decimal`](https://python-all.ru/3.1/library/decimal.html#decimal.Decimal)?18661867A. Да, все двоичные числа с плавающей запятой могут быть точно представлены как Decimal. Точное преобразование может потребовать большей точности, чем можно предположить интуитивно, поэтому мы перехватываем [`Inexact`](https://python-all.ru/3.1/library/decimal.html#decimal.Inexact), чтобы сигнализировать о необходимости большей точности:18681869```python1870def float_to_decimal(f):1871    "Convert a floating point number to a Decimal with no loss of information"1872    n, d = f.as_integer_ratio()1873    with localcontext() as ctx:1874        ctx.traps[Inexact] = True1875        while True:1876            try:1877               return Decimal(n) / Decimal(d)1878            except Inexact:1879                ctx.prec += 11880```18811882```python1883>>> float_to_decimal(math.pi)1884Decimal('3.141592653589793115997963468544185161590576171875')1885```18861887Q. Почему функция `float_to_decimal()` не включена в модуль?18881889A. Ведутся споры о том, стоит ли смешивать двоичные и десятичные числа с плавающей запятой. Кроме того, ее использование требует осторожности, чтобы избежать проблем представления, связанных с двоичной плавающей запятой:18901891```python1892>>> float_to_decimal(1.1)1893Decimal('1.100000000000000088817841970012523233890533447265625')1894```18951896Вопрос. В сложном вычислении как я могу убедиться, что не получил ложный результат из-за недостаточной точности или аномалий округления?18971898Ответ. Модуль decimal упрощает проверку результатов. Рекомендуется перезапускать вычисления с большей точностью и различными режимами округления. Сильно различающиеся результаты указывают на недостаточную точность, проблемы с режимом округления, плохо обусловленные входные данные или численно неустойчивый алгоритм.18991900Вопрос. Я заметил, что точность контекста применяется к результатам операций, но не к входным данным. Есть ли что-то, на что следует обращать внимание при смешивании значений разной точности?19011902Ответ. Да. Принцип заключается в том, что все значения считаются точными, как и арифметические операции с ними. Округляются только результаты. Преимущество для входных данных в том, что «что ввёл, то и получил». Недостаток в том, что результаты могут выглядеть странно, если забыть, что входные данные не округлены:19031904```python1905>>> getcontext().prec = 31906>>> Decimal('3.104') + Decimal('2.104')1907Decimal('5.21')1908>>> Decimal('3.104') + Decimal('0.000') + Decimal('2.104')1909Decimal('5.20')1910```19111912Решение – либо увеличить точность, либо принудительно округлить входные данные с помощью унарного плюса:19131914```python1915>>> getcontext().prec = 31916>>> +Decimal('1.23456789')      # Унарный плюс вызывает округление1917Decimal('1.23')1918```19191920Alternatively, inputs can be rounded upon creation using the [`Context.create_decimal()`](https://python-all.ru/3.1/library/decimal.html#decimal.Context.create_decimal) method:19211922```python1923>>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')1924Decimal('1.2345')1925```1926