decimal.md
1> **Источник:** https://python-all.ru/3.4/library/decimal.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 9.4. [`decimal`](https://python-all.ru/3.4/library/decimal.html#module-decimal) – Десятичная арифметика с фиксированной и плавающей точкой89Модуль [`decimal`](https://python-all.ru/3.4/library/decimal.html#module-decimal) обеспечивает поддержку быстрой и правильно округлённой десятичной арифметики с плавающей точкой. Он даёт несколько преимуществ по сравнению с типом данных [`float`](https://python-all.ru/3.4/library/functions.html#float):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`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_CEILING), [`ROUND_DOWN`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_DOWN), [`ROUND_FLOOR`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_FLOOR), [`ROUND_HALF_DOWN`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_HALF_DOWN), [`ROUND_HALF_EVEN`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_HALF_EVEN), [`ROUND_HALF_UP`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_HALF_UP), [`ROUND_UP`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_UP) и [`ROUND_05UP`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_05UP).3435Сигналы – это группы исключительных ситуаций, возникающих в ходе вычислений. В зависимости от потребностей приложения сигналы могут игнорироваться, рассматриваться как информационные или обрабатываться как исключения. Сигналы в модуле decimal: [`Clamped`](https://python-all.ru/3.4/library/decimal.html#decimal.Clamped), [`InvalidOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.InvalidOperation), [`DivisionByZero`](https://python-all.ru/3.4/library/decimal.html#decimal.DivisionByZero), [`Inexact`](https://python-all.ru/3.4/library/decimal.html#decimal.Inexact), [`Rounded`](https://python-all.ru/3.4/library/decimal.html#decimal.Rounded), [`Subnormal`](https://python-all.ru/3.4/library/decimal.html#decimal.Subnormal), [`Overflow`](https://python-all.ru/3.4/library/decimal.html#decimal.Overflow), [`Underflow`](https://python-all.ru/3.4/library/decimal.html#decimal.Underflow) и [`FloatOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.FloatOperation).3637Для каждого сигнала существует флаг и активатор ловушки. Когда сигнал обнаруживается, его флаг устанавливается в единицу, затем, если активатор ловушки установлен в единицу, возбуждается исключение. Флаги сохраняют состояние, поэтому пользователю необходимо сбрасывать их перед мониторингом вычислений.3839> **См. также**40>41> - Спецификация общей десятичной арифметики IBM, [Общая спецификация десятичной арифметики](https://python-all.ru/3.4/library/decimal.html).42> - Стандарт IEEE 854-1987, [Неофициальный текст IEEE 854](https://python-all.ru/3.4/library/decimal.html).4344## 9.4.1. Краткое руководство4546Обычно для работы с десятичными числами модуль импортируют, просматривают текущий контекст с помощью [`getcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.getcontext) и, при необходимости, устанавливают новые значения точности, округления или включённых ловушек:4748```python49>>> from decimal import *50>>> getcontext()51Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,52 capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero,53 InvalidOperation])5455>>> getcontext().prec = 7 # Установить новую точность56```5758Экземпляры Decimal можно создавать из целых чисел, строк, чисел с плавающей точкой или кортежей. Создание из целого числа или числа с плавающей точкой выполняет точное преобразование значения этого целого числа или числа с плавающей точкой. Десятичные числа включают специальные значения, такие как `NaN`, что означает «Не число», положительную и отрицательную `Infinity` и `-0`:5960```python61>>> getcontext().prec = 2862>>> Decimal(10)63Decimal('10')64>>> Decimal('3.14')65Decimal('3.14')66>>> Decimal(3.14)67Decimal('3.140000000000000124344978758017532527446746826171875')68>>> Decimal((0, (3, 1, 4), -2))69Decimal('3.14')70>>> Decimal(str(2.0 ** 0.5))71Decimal('1.4142135623730951')72>>> Decimal(2) ** Decimal('0.5')73Decimal('1.414213562373095048801688724')74>>> Decimal('NaN')75Decimal('NaN')76>>> Decimal('-Infinity')77Decimal('-Infinity')78```7980Если для сигнала [`FloatOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.FloatOperation) установлена ловушка, случайное смешивание десятичных чисел и чисел с плавающей точкой в конструкторах или при сравнении порядка вызывает исключение:8182```python83>>> c = getcontext()84>>> c.traps[FloatOperation] = True85>>> Decimal(3.14)86Traceback (most recent call last):87File "<stdin>", line 1, in <module>88decimal.FloatOperation: [<class 'decimal.FloatOperation'>]89>>> Decimal('3.5') < 3.790Traceback (most recent call last):91 File "<stdin>", line 1, in <module>92decimal.FloatOperation: [<class 'decimal.FloatOperation'>]93>>> Decimal('3.5') == 3.594True95```9697Новое в версии 3.3.9899Значимость нового Decimal определяется исключительно количеством введённых цифр. Точность контекста и округление вступают в силу только во время арифметических операций.100101```python102>>> getcontext().prec = 6103>>> Decimal('3.0')104Decimal('3.0')105>>> Decimal('3.1415926535')106Decimal('3.1415926535')107>>> Decimal('3.1415926535') + Decimal('2.7182818285')108Decimal('5.85987')109>>> getcontext().rounding = ROUND_UP110>>> Decimal('3.1415926535') + Decimal('2.7182818285')111Decimal('5.85988')112```113114Если превышены внутренние ограничения C-версии, создание десятичного числа вызывает [`InvalidOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.InvalidOperation):115116```python117>>> Decimal("1e9999999999999999999")118Traceback (most recent call last):119 File "<stdin>", line 1, in <module>120decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]121```122123Изменено в версии 3.3.124125Десятичные числа хорошо взаимодействуют с остальной частью Python. Вот небольшой пример разнообразия десятичной арифметики с плавающей точкой:126127```python128>>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))129>>> max(data)130Decimal('9.25')131>>> min(data)132Decimal('0.03')133>>> sorted(data)134[Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),135 Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]136>>> sum(data)137Decimal('19.29')138>>> a,b,c = data[:3]139>>> str(a)140'1.34'141>>> float(a)1421.34143>>> round(a, 1)144Decimal('1.3')145>>> int(a)1461147>>> a * 5148Decimal('6.70')149>>> a * b150Decimal('2.5058')151>>> c % a152Decimal('0.77')153```154155Также некоторые математические функции доступны для Decimal:156157```python158>>> getcontext().prec = 28159>>> Decimal(2).sqrt()160Decimal('1.414213562373095048801688724')161>>> Decimal(1).exp()162Decimal('2.718281828459045235360287471')163>>> Decimal('10').ln()164Decimal('2.302585092994045684017991455')165>>> Decimal('10').log10()166Decimal('1')167```168169Метод `quantize()` округляет число до заданного показателя степени. Этот метод полезен для денежных приложений, которые часто округляют результаты до фиксированного количества знаков:170171```python172>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)173Decimal('7.32')174>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)175Decimal('8')176```177178Как показано выше, функция [`getcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.getcontext) обращается к текущему контексту и позволяет изменять настройки. Такой подход удовлетворяет потребности большинства приложений.179180Для более сложной работы может быть полезно создавать альтернативные контексты с помощью конструктора Context(). Чтобы сделать альтернативный контекст активным, используйте функцию [`setcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.setcontext).181182В соответствии со стандартом модуль [`decimal`](https://python-all.ru/3.4/library/decimal.html#module-decimal) предоставляет два готовых к использованию стандартных контекста: [`BasicContext`](https://python-all.ru/3.4/library/decimal.html#decimal.BasicContext) и [`ExtendedContext`](https://python-all.ru/3.4/library/decimal.html#decimal.ExtendedContext). Первый особенно полезен для отладки, поскольку многие ловушки в нём включены:183184```python185>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)186>>> setcontext(myothercontext)187>>> Decimal(1) / Decimal(7)188Decimal('0.142857142857142857142857142857142857142857142857142857142857')189190>>> ExtendedContext191Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,192 capitals=1, clamp=0, flags=[], traps=[])193>>> setcontext(ExtendedContext)194>>> Decimal(1) / Decimal(7)195Decimal('0.142857143')196>>> Decimal(42) / Decimal(0)197Decimal('Infinity')198199>>> setcontext(BasicContext)200>>> Decimal(42) / Decimal(0)201Traceback (most recent call last):202 File "<pyshell#143>", line 1, in -toplevel-203 Decimal(42) / Decimal(0)204DivisionByZero: x / 0205```206207Контексты также имеют флаги сигналов для отслеживания исключительных ситуаций, возникающих во время вычислений. Флаги остаются установленными до явного сброса, поэтому лучше всего сбрасывать флаги перед каждой серией отслеживаемых вычислений с помощью метода `clear_flags()`.208209```python210>>> setcontext(ExtendedContext)211>>> getcontext().clear_flags()212>>> Decimal(355) / Decimal(113)213Decimal('3.14159292')214>>> getcontext()215Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,216 capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])217```218219Запись *flags* показывает, что рациональное приближение к `Pi` было округлено (цифры за пределами точности контекста были отброшены) и что результат неточен (некоторые отброшенные цифры были ненулевыми).220221Отдельные ловушки устанавливаются с помощью словаря в поле `traps` контекста:222223```python224>>> setcontext(ExtendedContext)225>>> Decimal(1) / Decimal(0)226Decimal('Infinity')227>>> getcontext().traps[DivisionByZero] = 1228>>> Decimal(1) / Decimal(0)229Traceback (most recent call last):230 File "<pyshell#112>", line 1, in -toplevel-231 Decimal(1) / Decimal(0)232DivisionByZero: x / 0233```234235Большинство программ настраивают текущий контекст только один раз, в начале программы. И во многих приложениях данные преобразуются в [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) с помощью одного приведения в цикле. После установки контекста и создания десятичных чисел основная часть программы манипулирует данными точно так же, как и с другими числовыми типами Python.236237## 9.4.2. Объекты Decimal238239#### `class decimal.Decimal(value="0", context=None)`240241Создаёт новый объект [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) на основе *value*.242243*value* может быть целым числом, строкой, кортежем, [`float`](https://python-all.ru/3.4/library/functions.html#float) или другим объектом [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal). Если *value* не указан, возвращается `Decimal('0')`. Если *value* – строка, она должна соответствовать синтаксису десятичной числовой строки после удаления начальных и конечных пробельных символов:244245```python246sign ::= '+' | '-'247digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'248indicator ::= 'e' | 'E'249digits ::= digit [digit]...250decimal-part ::= digits '.' [digits] | ['.'] digits251exponent-part ::= indicator [sign] digits252infinity ::= 'Infinity' | 'Inf'253nan ::= 'NaN' [digits] | 'sNaN' [digits]254numeric-value ::= decimal-part [exponent-part] | infinity255numeric-string ::= [sign] numeric-value | [sign] nan256```257258Другие десятичные цифры Unicode также допускаются там, где выше указано `digit`. К ним относятся десятичные цифры из различных других алфавитов (например, арабо-индийские цифры и деванагари), а также полноширинные цифры от `'\uff10'` до `'\uff19'`.259260Если *value* является [`tuple`](https://python-all.ru/3.4/library/stdtypes.html#tuple), он должен иметь три компонента: знак (`0` для положительного или `1` для отрицательного), [`tuple`](https://python-all.ru/3.4/library/stdtypes.html#tuple) цифр и целочисленный показатель степени. Например, `Decimal((0, (1, 4, 1, 4), -3))` возвращает `Decimal('1.414')`.261262Если *value* является [`float`](https://python-all.ru/3.4/library/functions.html#float), двоичное значение с плавающей точкой без потерь преобразуется в его точный десятичный эквивалент. Это преобразование часто может потребовать 53 или более цифр точности. Например, `Decimal(float('1.1'))` преобразуется в `Decimal('1.100000000000000088817841970012523233890533447265625')`.263264Точность *context* не влияет на количество сохраняемых цифр. Оно определяется исключительно количеством цифр в *value*. Например, `Decimal('3.00000')` сохраняет все пять нулей, даже если точность контекста равна только трём.265266Назначение аргумента *context* – определить, что делать, если *value* является некорректной строкой. Если контекст перехватывает сигнал [`InvalidOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.InvalidOperation), вызывается исключение; в противном случае конструктор возвращает новый Decimal со значением `NaN`.267268После создания объекты [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) являются неизменяемыми.269270Изменено в версии 3.2: Теперь аргумент конструктора может быть экземпляром [`float`](https://python-all.ru/3.4/library/functions.html#float).271272Изменено в версии 3.3: Аргументы [`float`](https://python-all.ru/3.4/library/functions.html#float) вызывают исключение, если установлена ловушка [`FloatOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.FloatOperation). По умолчанию ловушка выключена.273274Объекты Decimal имеют много общего с другими встроенными числовыми типами, такими как [`float`](https://python-all.ru/3.4/library/functions.html#float) и [`int`](https://python-all.ru/3.4/library/functions.html#int). Для них определены все стандартные математические операции и специальные методы. Кроме того, десятичные объекты можно копировать, сериализовать (pickle), выводить на печать, использовать в качестве ключей словаря, элементов множества, сравнивать, сортировать и преобразовывать в другой тип (например, [`float`](https://python-all.ru/3.4/library/functions.html#float) или [`int`](https://python-all.ru/3.4/library/functions.html#int)).275276Существуют небольшие различия между арифметикой над объектами Decimal и арифметикой над целыми числами и числами с плавающей запятой. Когда оператор остатка `%` применяется к объектам Decimal, знак результата совпадает со знаком *dividend*, а не со знаком делителя:277278```python279>>> (-7) % 42801281>>> Decimal(-7) % Decimal(4)282Decimal('-3')283```284285Оператор целочисленного деления `//` ведёт себя аналогично: возвращает целую часть истинного частного (с округлением в сторону нуля), а не его пол, чтобы сохранить обычное тождество `x == (x // y) * y + x % y`:286287```python288>>> -7 // 4289-2290>>> Decimal(-7) // Decimal(4)291Decimal('-1')292```293294Операторы `%` и `//` реализуют операции `остаток` и `целочисленное-деление` (соответственно) в соответствии со спецификацией.295296Объекты Decimal обычно нельзя комбинировать с числами float или экземплярами [`fractions.Fraction`](https://python-all.ru/3.4/library/fractions.html#fractions.Fraction) в арифметических операциях: попытка добавить [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) к [`float`](https://python-all.ru/3.4/library/functions.html#float), например, вызовет [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError). Однако можно использовать операторы сравнения Python для сравнения экземпляра [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) `x` с другим числом `y`. Это позволяет избежать путаницы при проверках на равенство между числами разных типов.297298Изменено в версии 3.2: Сравнения смешанных типов между экземплярами [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) и другими числовыми типами теперь полностью поддерживаются.299300В дополнение к стандартным числовым свойствам десятичные объекты с плавающей точкой также имеют ряд специализированных методов:301302#### `adjusted()`303304Возвращает скорректированный показатель степени после удаления крайних правых цифр коэффициента, пока не останется только старшая цифра: `Decimal('321e+5').adjusted()` возвращает семь. Используется для определения положения самой значащей цифры относительно десятичной точки.305306#### `as_tuple()`307308Возвращает представление числа в виде [*именованного кортежа*](https://python-all.ru/3.4/glossary.html#term-named-tuple): `DecimalTuple(sign, digits, exponent)`.309310#### `canonical()`311312Возвращает каноническую кодировку аргумента. В настоящее время кодировка экземпляра [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) всегда канонична, поэтому эта операция возвращает свой аргумент без изменений.313314#### `compare(other, context=None)`315316Сравнивает значения двух экземпляров Decimal. [`compare()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.compare) возвращает экземпляр Decimal, и если любой из операндов является NaN, то результатом будет NaN:317318```python319a or b is a NaN ==> Decimal('NaN')320a < b ==> Decimal('-1')321a == b ==> Decimal('0')322a > b ==> Decimal('1')323```324325#### `compare_signal(other, context=None)`326327Эта операция идентична методу [`compare()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.compare), за исключением того, что все NaN сигнализируют. То есть, если ни один операнд не является сигнальным NaN, то любой тихий NaN обрабатывается так, как если бы он был сигнальным NaN.328329#### `compare_total(other, context=None)`330331Сравнивает два операнда, используя их абстрактное представление, а не числовое значение. Аналогично методу [`compare()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.compare), но результат даёт полное упорядочение экземпляров [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal). Два экземпляра [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) с одинаковым числовым значением, но разными представлениями сравниваются как неравные в этом упорядочении:332333```python334>>> Decimal('12.0').compare_total(Decimal('12'))335Decimal('-1')336```337338Тихие и сигнальные NaN также включены в полное упорядочение. Результат этой функции равен `Decimal('0')`, если оба операнда имеют одинаковое представление, `Decimal('-1')`, если первый операнд находится ниже в полном порядке, чем второй, и `Decimal('1')`, если первый операнд находится выше в полном порядке, чем второй операнд. Подробнее о полном порядке см. в спецификации.339340Эта операция не зависит от контекста и является тихой: никакие флаги не меняются и округление не выполняется. Исключение составляет C-версия, которая может возбудить InvalidOperation, если второй операнд невозможно точно преобразовать.341342#### `compare_total_mag(other, context=None)`343344Сравнивает два операнда, используя их абстрактное представление, а не их значение, как в [`compare_total()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.compare_total), но игнорируя знак каждого операнда. `x.compare_total_mag(y)` эквивалентно `x.copy_abs().compare_total(y.copy_abs())`.345346Эта операция не зависит от контекста и является тихой: никакие флаги не меняются и округление не выполняется. Исключение составляет C-версия, которая может возбудить InvalidOperation, если второй операнд невозможно точно преобразовать.347348#### `conjugate()`349350Просто возвращает self; этот метод существует только для соответствия спецификации Decimal.351352#### `copy_abs()`353354Возвращает абсолютное значение аргумента. Эта операция не зависит от контекста и является тихой: флаги не изменяются и округление не выполняется.355356#### `copy_negate()`357358Возвращает отрицание аргумента. Эта операция не зависит от контекста и является тихой: флаги не изменяются и округление не выполняется.359360#### `copy_sign(other, context=None)`361362Возвращает копию первого операнда со знаком, установленным таким же, как знак второго операнда. Например:363364```python365>>> Decimal('2.3').copy_sign(Decimal('-1.5'))366Decimal('-2.3')367```368369Эта операция не зависит от контекста и является тихой: никакие флаги не меняются и округление не выполняется. Исключение составляет C-версия, которая может возбудить InvalidOperation, если второй операнд невозможно точно преобразовать.370371#### `exp(context=None)`372373Возвращает значение (натуральной) экспоненциальной функции `e**x` для данного числа. Результат правильно округляется с использованием режима округления [`ROUND_HALF_EVEN`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_HALF_EVEN).374375```python376>>> Decimal(1).exp()377Decimal('2.718281828459045235360287471')378>>> Decimal(321).exp()379Decimal('2.561702493119680037517373933E+139')380```381382#### `from_float(f)`383384Метод класса, который преобразует число с плавающей точкой в десятичное число точно.385386Примечание: *Decimal.from\_float(0.1)* не то же самое, что *Decimal('0.1')*. Поскольку 0.1 нельзя точно представить в двоичной арифметике с плавающей точкой, значение хранится как ближайшее представимое значение, равное *0x1.999999999999ap-4*. Эквивалентное десятичное значение – это *0.1000000000000000055511151231257827021181583404541015625*.387388> **Примечание**389>390> Начиная с Python 3.2, экземпляр [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) также можно создать напрямую из [`float`](https://python-all.ru/3.4/library/functions.html#float).391392```python393>>> Decimal.from_float(0.1)394Decimal('0.1000000000000000055511151231257827021181583404541015625')395>>> Decimal.from_float(float('nan'))396Decimal('NaN')397>>> Decimal.from_float(float('inf'))398Decimal('Infinity')399>>> Decimal.from_float(float('-inf'))400Decimal('-Infinity')401```402403Новое в версии 3.1.404405#### `fma(other, third, context=None)`406407Совмещённое умножение-сложение. Возвращает self\*other+third без округления промежуточного произведения self\*other.408409```python410>>> Decimal(2).fma(3, 5)411Decimal('11')412```413414#### `is_canonical()`415416Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент каноничен, и [`False`](https://python-all.ru/3.4/library/constants.html#False) в противном случае. В настоящее время экземпляр [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) всегда каноничен, поэтому эта операция всегда возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True).417418#### `is_finite()`419420Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент является конечным числом, и [`False`](https://python-all.ru/3.4/library/constants.html#False), если аргумент является бесконечностью или NaN.421422#### `is_infinite()`423424Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент – положительная или отрицательная бесконечность, и [`False`](https://python-all.ru/3.4/library/constants.html#False) в противном случае.425426#### `is_nan()`427428Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент – тихий или сигнализирующий NaN, и [`False`](https://python-all.ru/3.4/library/constants.html#False) в противном случае.429430#### `is_normal(context=None)`431432Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент – *нормальное* конечное число. Возвращает [`False`](https://python-all.ru/3.4/library/constants.html#False), если аргумент – ноль, субнормальное число, бесконечность или NaN.433434#### `is_qnan()`435436Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент – тихий NaN, и [`False`](https://python-all.ru/3.4/library/constants.html#False) в противном случае.437438#### `is_signed()`439440Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент имеет отрицательный знак, и [`False`](https://python-all.ru/3.4/library/constants.html#False) в противном случае. Обратите внимание, что нули и NaN могут иметь знак.441442#### `is_snan()`443444Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент – сигнализирующий NaN, и [`False`](https://python-all.ru/3.4/library/constants.html#False) в противном случае.445446#### `is_subnormal(context=None)`447448Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент субнормальный, и [`False`](https://python-all.ru/3.4/library/constants.html#False) в противном случае.449450#### `is_zero()`451452Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если аргумент – (положительный или отрицательный) ноль, и [`False`](https://python-all.ru/3.4/library/constants.html#False) в противном случае.453454#### `ln(context=None)`455456Возвращает натуральный (по основанию e) логарифм операнда. Результат корректно округляется с использованием режима округления [`ROUND_HALF_EVEN`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_HALF_EVEN).457458#### `log10(context=None)`459460Возвращает десятичный логарифм операнда. Результат корректно округляется с использованием режима округления [`ROUND_HALF_EVEN`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_HALF_EVEN).461462#### `logb(context=None)`463464Для ненулевого числа возвращает скорректированный порядок операнда в виде экземпляра [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal). Если операнд – ноль, то возвращается `Decimal('-Infinity')` и поднимается флаг [`DivisionByZero`](https://python-all.ru/3.4/library/decimal.html#decimal.DivisionByZero). Если операнд – бесконечность, то возвращается `Decimal('Infinity')`.465466#### `logical_and(other, context=None)`467468[`logical_and()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.logical_and) – логическая операция, принимающая два *логических операнда* (см. [*Логические операнды*](https://python-all.ru/3.4/library/decimal.html#logical-operands-label)). Результатом является поразрядное `И` двух операндов.469470#### `logical_invert(context=None)`471472[`logical_invert()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.logical_invert) – логическая операция. Результатом является поразрядная инверсия операнда.473474#### `logical_or(other, context=None)`475476[`logical_or()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.logical_or) – логическая операция, принимающая два *логических операнда* (см. [*Логические операнды*](https://python-all.ru/3.4/library/decimal.html#logical-operands-label)). Результатом является поразрядное `ИЛИ` двух операндов.477478#### `logical_xor(other, context=None)`479480[`logical_xor()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.logical_xor) – логическая операция, принимающая два *логических операнда* (см. [*Логические операнды*](https://python-all.ru/3.4/library/decimal.html#logical-operands-label)). Результатом является поразрядное исключающее ИЛИ двух операндов.481482#### `max(other, context=None)`483484Подобно `max(self, other)`, за исключением того, что правило округления контекста применяется перед возвратом, и что значения `NaN` либо сигнализируются, либо игнорируются (в зависимости от контекста и от того, являются ли они сигнализирующими или тихими).485486#### `max_mag(other, context=None)`487488Похож на метод [`max()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.max), но сравнение выполняется с использованием абсолютных значений операндов.489490#### `min(other, context=None)`491492Как и `min(self, other)`, но с одним отличием: правило округления контекста применяется перед возвратом результата, а значения `NaN` либо сигнализируются, либо игнорируются (в зависимости от контекста и от того, являются ли они сигнальными или тихими).493494#### `min_mag(other, context=None)`495496Похож на метод [`min()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.min), но сравнение выполняется с использованием абсолютных значений операндов.497498#### `next_minus(context=None)`499500Возвращает наибольшее число, представимое в заданном контексте (или в контексте текущего потока, если контекст не задан), которое меньше заданного операнда.501502#### `next_plus(context=None)`503504Возвращает наименьшее число, представимое в заданном контексте (или в контексте текущего потока, если контекст не задан), которое больше заданного операнда.505506#### `next_toward(other, context=None)`507508Если два операнда не равны, возвращает число, ближайшее к первому операнду в направлении второго операнда. Если оба операнда численно равны, возвращает копию первого операнда со знаком, установленным таким же, как знак второго операнда.509510#### `normalize(context=None)`511512Нормализует число, удаляя конечные нули справа и преобразуя любой результат, равный `Decimal('0')`, в `Decimal('0e0')`. Используется для получения канонических значений атрибутов класса эквивалентности. Например, `Decimal('32.100')` и `Decimal('0.321000e+2')` оба нормализуются до эквивалентного значения `Decimal('32.1')`.513514#### `number_class(context=None)`515516Возвращает строку, описывающую *класс* операнда. Возвращаемое значение является одной из следующих десяти строк.517518- `"-Infinity"` – указывает, что операнд является отрицательной бесконечностью.519- `"-Normal"` – указывает, что операнд является отрицательным нормальным числом.520- `"-Subnormal"` – указывает, что операнд отрицателен и является субнормальным.521- `"-Zero"` – указывает, что операнд является отрицательным нулём.522- `"+Zero"` – указывает, что операнд является положительным нулём.523- `"+Subnormal"` – указывает, что операнд положителен и является субнормальным.524- `"+Normal"` – указывает, что операнд является положительным нормальным числом.525- `"+Infinity"` – указывает, что операнд является положительной бесконечностью.526- `"NaN"` – указывает, что операнд является тихим NaN (не числом).527- `"sNaN"` – указывает, что операнд является сигнальным NaN.528529#### `quantize(exp, rounding=None, context=None, watchexp=True)`530531Возвращает значение, равное первому операнду после округления и имеющее экспоненту второго операнда.532533```python534>>> Decimal('1.41421356').quantize(Decimal('1.000'))535Decimal('1.414')536```537538В отличие от других операций, если длина коэффициента после операции quantize превышает точность, то сигнализируется [`InvalidOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.InvalidOperation). Это гарантирует, что при отсутствии ошибки квантованный порядок всегда равен порядку правого операнда.539540Также, в отличие от других операций, quantize никогда не сигнализирует Underflow, даже если результат субнормален и неточен.541542Если порядок второго операнда больше порядка первого, то может потребоваться округление. В этом случае режим округления определяется аргументом `rounding`, если он задан, иначе – аргументом `context`; если не задан ни один аргумент, используется режим округления контекста текущего потока.543544Если *watchexp* установлен (по умолчанию), то ошибка возвращается всякий раз, когда результирующий порядок больше `Emax` или меньше `Etiny`.545546Устарело с версии 3.3: *watchexp* – деталь реализации из версии на чистом Python и отсутствует в версии на C. Будет удалено в версии 3.4, где по умолчанию `True`.547548#### `radix()`549550Возвращает `Decimal(10)` – основание системы счисления (базу), в которой класс [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) выполняет все свои арифметические операции. Включён для совместимости со спецификацией.551552#### `remainder_near(other, context=None)`553554Возвращает остаток от деления *self* на *other*. Отличается от `self % other` тем, что знак остатка выбирается так, чтобы минимизировать его абсолютное значение. Точнее, возвращаемое значение равно `self - n * other`, где `n` – целое число, ближайшее к точному значению `self / other`, а если два целых числа одинаково близки, то выбирается чётное.555556Если результат равен нулю, его знак будет знаком *self*.557558```python559>>> Decimal(18).remainder_near(Decimal(10))560Decimal('-2')561>>> Decimal(25).remainder_near(Decimal(10))562Decimal('5')563>>> Decimal(35).remainder_near(Decimal(10))564Decimal('-5')565```566567#### `rotate(other, context=None)`568569Возвращает результат вращения цифр первого операнда на величину, заданную вторым операндом. Второй операнд должен быть целым числом в диапазоне от -precision до precision. Абсолютное значение второго операнда задаёт количество позиций для вращения. Если второй операнд положителен, вращение выполняется влево; в противном случае вращение выполняется вправо. Коэффициент первого операнда при необходимости дополняется слева нулями до длины precision. Знак и экспонента первого операнда не изменяются.570571#### `same_quantum(other, context=None)`572573Проверяет, имеют ли self и other одинаковую экспоненту или оба являются `NaN`.574575Эта операция не зависит от контекста и является тихой: никакие флаги не меняются и округление не выполняется. Исключение составляет C-версия, которая может возбудить InvalidOperation, если второй операнд невозможно точно преобразовать.576577#### `scaleb(other, context=None)`578579Возвращает первый операнд с экспонентой, скорректированной на второй. Эквивалентно умножению первого операнда на `10**other`. Второй операнд должен быть целым числом.580581#### `shift(other, context=None)`582583Возвращает результат сдвига цифр первого операнда на величину, заданную вторым операндом. Второй операнд должен быть целым числом в диапазоне от -precision до precision. Абсолютное значение второго операнда задаёт количество позиций для сдвига. Если второй операнд положителен, сдвиг выполняется влево; в противном случае сдвиг выполняется вправо. Вдвигаемые в коэффициент цифры являются нулями. Знак и экспонента первого операнда не изменяются.584585#### `sqrt(context=None)`586587Возвращает квадратный корень аргумента с полной точностью.588589#### `to_eng_string(context=None)`590591Преобразует в строку инженерного типа.592593Инженерная нотация использует экспоненту, кратную 3, поэтому слева от десятичной точки может быть до 3 цифр. Например, преобразует `Decimal('123E+1')` в `Decimal('1.23E+3')`.594595#### `to_integral(rounding=None, context=None)`596597Идентичен методу [`to_integral_value()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.to_integral_value). Имя `to_integral` сохранено для совместимости со старыми версиями.598599#### `to_integral_exact(rounding=None, context=None)`600601Округляет до ближайшего целого, сигнализируя [`Inexact`](https://python-all.ru/3.4/library/decimal.html#decimal.Inexact) или [`Rounded`](https://python-all.ru/3.4/library/decimal.html#decimal.Rounded) в зависимости от того, произошло ли округление. Режим округления определяется параметром `rounding`, если он задан, иначе – заданным `context`. Если ни один параметр не задан, используется режим округления текущего контекста.602603#### `to_integral_value(rounding=None, context=None)`604605Округляет до ближайшего целого без сигнализации [`Inexact`](https://python-all.ru/3.4/library/decimal.html#decimal.Inexact) или [`Rounded`](https://python-all.ru/3.4/library/decimal.html#decimal.Rounded). Если задан, применяет *rounding*; в противном случае использует метод округления из предоставленного *context* или текущего контекста.606607### 9.4.2.1. Логические операнды608609Методы `logical_and()`, `logical_invert()`, `logical_or()` и `logical_xor()` ожидают, что их аргументы являются *логическими операндами*. *Логический операнд* – это экземпляр [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal), у которого экспонента и знак равны нулю, а цифры – либо `0`, либо `1`.610611## 9.4.3. Объекты контекста612613Контексты – это среды для арифметических операций. Они управляют точностью, задают правила округления, определяют, какие сигналы обрабатываются как исключения, и ограничивают диапазон для экспонент.614615Каждый поток имеет свой собственный текущий контекст, доступ к которому осуществляется или изменяется с помощью функций [`getcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.getcontext) и [`setcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.setcontext).616617#### `decimal.getcontext()`618619Возвращает текущий контекст активного потока.620621#### `decimal.setcontext(c)`622623Устанавливает текущий контекст активного потока в *c*.624625Также можно использовать оператор [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with) и функцию [`localcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.localcontext) для временного изменения активного контекста.626627#### `decimal.localcontext(ctx=None)`628629Возвращает менеджер контекста, который устанавливает текущий контекст для активного потока в копию *ctx* при входе в инструкцию with и восстанавливает предыдущий контекст при выходе из инструкции with. Если контекст не указан, используется копия текущего контекста.630631Например, следующий код устанавливает текущую точность десятичных чисел в 42 знака, выполняет вычисление и затем автоматически восстанавливает предыдущий контекст:632633```python634from decimal import localcontext635636with localcontext() as ctx:637 ctx.prec = 42 # Выполнить вычисление с высокой точностью638 s = calculate_something()639s = +s # Округлить конечный результат до стандартной точности640```641642Новые контексты также можно создавать с помощью конструктора [`Context`](https://python-all.ru/3.4/library/decimal.html#decimal.Context), описанного ниже. Кроме того, модуль предоставляет три готовых контекста:643644#### `class decimal.BasicContext`645646Это стандартный контекст, определённый в спецификации General Decimal Arithmetic. Точность установлена в девять. Режим округления – [`ROUND_HALF_UP`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_HALF_UP). Все флаги сброшены. Все ловушки включены (обрабатываются как исключения), кроме [`Inexact`](https://python-all.ru/3.4/library/decimal.html#decimal.Inexact), [`Rounded`](https://python-all.ru/3.4/library/decimal.html#decimal.Rounded) и [`Subnormal`](https://python-all.ru/3.4/library/decimal.html#decimal.Subnormal).647648Поскольку многие ловушки включены, этот контекст полезен для отладки.649650#### `class decimal.ExtendedContext`651652Это стандартный контекст, определённый в спецификации General Decimal Arithmetic. Точность установлена в девять. Режим округления – [`ROUND_HALF_EVEN`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_HALF_EVEN). Все флаги сброшены. Никакие ловушки не включены (чтобы во время вычислений не возникали исключения).653654Поскольку ловушки отключены, этот контекст полезен для приложений, которые предпочитают получать значение `NaN` или `Infinity` вместо вызова исключений. Это позволяет приложению завершить выполнение при наличии условий, которые в противном случае остановили бы программу.655656#### `class decimal.DefaultContext`657658Этот контекст используется конструктором [`Context`](https://python-all.ru/3.4/library/decimal.html#decimal.Context) в качестве прототипа для новых контекстов. Изменение поля (например, точности) меняет значение по умолчанию для новых контекстов, создаваемых конструктором [`Context`](https://python-all.ru/3.4/library/decimal.html#decimal.Context).659660Этот контекст наиболее полезен в многопоточных средах. Изменение одного из полей до запуска потоков приводит к установке общесистемных значений по умолчанию. Изменять поля после запуска потоков не рекомендуется, так как это потребовало бы синхронизации потоков для предотвращения состояний гонки.661662В однопоточных средах лучше вообще не использовать этот контекст. Вместо этого просто создавайте контексты явно, как описано ниже.663664Значения по умолчанию: `prec`=`28`, `rounding`=[`ROUND_HALF_EVEN`](https://python-all.ru/3.4/library/decimal.html#decimal.ROUND_HALF_EVEN), и включены ловушки для [`Overflow`](https://python-all.ru/3.4/library/decimal.html#decimal.Overflow), [`InvalidOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.InvalidOperation) и [`DivisionByZero`](https://python-all.ru/3.4/library/decimal.html#decimal.DivisionByZero).665666В дополнение к трём предоставленным контекстам новые контексты можно создавать с помощью конструктора [`Context`](https://python-all.ru/3.4/library/decimal.html#decimal.Context).667668#### `class decimal.Context(prec=None, rounding=None, Emin=None, Emax=None, capitals=None, clamp=None, flags=None, traps=None)`669670Создаёт новый контекст. Если поле не указано или равно [`None`](https://python-all.ru/3.4/library/constants.html#None), значения по умолчанию копируются из [`DefaultContext`](https://python-all.ru/3.4/library/decimal.html#decimal.DefaultContext). Если поле *flags* не указано или равно [`None`](https://python-all.ru/3.4/library/constants.html#None), все флаги сбрасываются.671672*prec* – целое число в диапазоне \[`1`, [`MAX_PREC`](https://python-all.ru/3.4/library/decimal.html#decimal.MAX_PREC)\], задающее точность арифметических операций в контексте.673674Параметр *rounding* – это одна из констант, перечисленных в разделе [Режимы округления](https://python-all.ru/3.4/library/decimal.html#rounding-modes).675676Поля *traps* и *flags* содержат список сигналов, которые необходимо установить. Как правило, для новых контекстов следует задавать только ловушки (traps), а флаги (flags) оставлять сброшенными.677678Поля *Emin* и *Emax* – целые числа, задающие допустимые внешние границы для показателей степени. *Emin* должно быть в диапазоне \[[`MIN_EMIN`](https://python-all.ru/3.4/library/decimal.html#decimal.MIN_EMIN), `0`\], а *Emax* – в диапазоне \[`0`, [`MAX_EMAX`](https://python-all.ru/3.4/library/decimal.html#decimal.MAX_EMAX)\].679680Поле *capitals* может быть равно `0` или `1` (по умолчанию). Если установлено в `1`, показатели степени выводятся с заглавной `E`; в противном случае используется строчная `e`: `Decimal('6.02e+23')`.681682Поле *clamp* может быть равно `0` (по умолчанию) или `1`. Если установлено в `1`, показатель степени `e` экземпляра [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal), представимого в этом контексте, строго ограничивается диапазоном `Emin - prec + 1 <= e <= Emax - prec + 1`. Если *clamp* равно `0`, то выполняется более слабое условие: скорректированный показатель степени экземпляра [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) не превышает `Emax`. Когда *clamp* равно `1`, большое нормальное число, по возможности, уменьшает свой показатель степени и добавляет соответствующее количество нулей к коэффициенту, чтобы соблюсти ограничения на показатель степени; это сохраняет значение числа, но теряет информацию о значимых конечных нулях. Например:683684```python685>>> Context(prec=6, Emax=999, clamp=1).create_decimal('1.23e999')686Decimal('1.23000E+999')687```688689Значение *clamp*, равное `1`, обеспечивает совместимость с форматами обмена десятичными числами фиксированной ширины, определёнными в IEEE 754.690691Класс [`Context`](https://python-all.ru/3.4/library/decimal.html#decimal.Context) определяет несколько методов общего назначения, а также большое количество методов для непосредственного выполнения арифметических операций в заданном контексте. Кроме того, для каждого из методов [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal), описанных выше (за исключением методов `adjusted()` и `as_tuple()`), существует соответствующий метод [`Context`](https://python-all.ru/3.4/library/decimal.html#decimal.Context). Например, для экземпляра [`Context`](https://python-all.ru/3.4/library/decimal.html#decimal.Context) `C` и экземпляра [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) `x` вызов `C.exp(x)` эквивалентен `x.exp(context=C)`. Каждый метод [`Context`](https://python-all.ru/3.4/library/decimal.html#decimal.Context) принимает целое число Python (экземпляр [`int`](https://python-all.ru/3.4/library/functions.html#int)) везде, где ожидается экземпляр Decimal.692693#### `clear_flags()`694695Сбрасывает все флаги в `0`.696697#### `clear_traps()`698699Сбрасывает все ловушки в `0`.700701Новое в версии 3.3.702703#### `copy()`704705Возвращает копию контекста.706707#### `copy_decimal(num)`708709Возвращает копию экземпляра Decimal num.710711#### `create_decimal(num)`712713Создаёт новый экземпляр Decimal из *num*, используя *self* в качестве контекста. В отличие от конструктора [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal), при преобразовании применяются точность контекста, метод округления, флаги и ловушки.714715Это полезно, поскольку константы часто задаются с большей точностью, чем требуется приложению. Ещё одно преимущество в том, что округление немедленно устраняет нежелательные эффекты от цифр за пределами текущей точности. В следующем примере использование неокруглённых входных данных означает, что добавление нуля к сумме может изменить результат:716717```python718>>> getcontext().prec = 3719>>> Decimal('3.4445') + Decimal('1.0023')720Decimal('4.45')721>>> Decimal('3.4445') + Decimal(0) + Decimal('1.0023')722Decimal('4.44')723```724725Этот метод реализует операцию преобразования в число из спецификации IBM. Если аргумент – строка, начальные и конечные пробелы не допускаются.726727#### `create_decimal_from_float(f)`728729Создаёт новый экземпляр Decimal из числа с плавающей запятой *f*, выполняя округление с использованием *self* в качестве контекста. В отличие от метода класса [`Decimal.from_float()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.from_float), при преобразовании применяются точность контекста, метод округления, флаги и ловушки.730731```python732>>> context = Context(prec=5, rounding=ROUND_DOWN)733>>> context.create_decimal_from_float(math.pi)734Decimal('3.1415')735>>> context = Context(prec=5, traps=[Inexact])736>>> context.create_decimal_from_float(math.pi)737Traceback (most recent call last):738 ...739decimal.Inexact: None740```741742Новое в версии 3.1.743744#### `Etiny()`745746Возвращает значение, равное `Emin - prec + 1`, которое является минимальным значением показателя степени для субнормальных результатов. В случае антипереполнения (underflow) показатель степени устанавливается равным [`Etiny`](https://python-all.ru/3.4/library/decimal.html#decimal.Context.Etiny).747748#### `Etop()`749750Возвращает значение, равное `Emax - prec + 1`.751752Обычный подход к работе с десятичными числами – создавать экземпляры [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal), а затем применять арифметические операции, которые выполняются в текущем контексте активного потока. Альтернативный подход – использовать методы контекста для вычислений в заданном контексте. Эти методы аналогичны методам класса [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) и здесь лишь кратко перечислены.753754#### `abs(x)`755756Возвращает абсолютное значение *x*.757758#### `add(x, y)`759760Возвращает сумму *x* и *y*.761762#### `canonical(x)`763764Возвращает тот же объект Decimal *x*.765766#### `compare(x, y)`767768Сравнивает *x* и *y* численно.769770#### `compare_signal(x, y)`771772Сравнивает значения двух операндов численно.773774#### `compare_total(x, y)`775776Сравнивает два операнда по их абстрактному представлению.777778#### `compare_total_mag(x, y)`779780Сравнивает два операнда по их абстрактному представлению, игнорируя знак.781782#### `copy_abs(x)`783784Возвращает копию *x* с установленным в 0 знаком.785786#### `copy_negate(x)`787788Возвращает копию *x* с инвертированным знаком.789790#### `copy_sign(x, y)`791792Копирует знак из *y* в *x*.793794#### `divide(x, y)`795796Возвращает *x*, делённое на *y*.797798#### `divide_int(x, y)`799800Возвращает *x*, делённое на *y*, с усечением до целого.801802#### `divmod(x, y)`803804Делит два числа и возвращает целую часть результата.805806#### `exp(x)`807808Возвращает *e \*\* x*.809810#### `fma(x, y, z)`811812Возвращает *x*, умноженное на *y*, плюс *z*.813814#### `is_canonical(x)`815816Возвращает `True`, если *x* каноничен; в противном случае возвращает `False`.817818#### `is_finite(x)`819820Возвращает `True`, если *x* конечен; в противном случае возвращает `False`.821822#### `is_infinite(x)`823824Возвращает `True`, если *x* бесконечен; в противном случае возвращает `False`.825826#### `is_nan(x)`827828Возвращает `True`, если *x* является qNaN или sNaN; в противном случае возвращает `False`.829830#### `is_normal(x)`831832Возвращает `True`, если *x* является нормальным числом; в противном случае возвращает `False`.833834#### `is_qnan(x)`835836Возвращает `True`, если *x* является тихим NaN; в противном случае возвращает `False`.837838#### `is_signed(x)`839840Возвращает `True`, если *x* отрицателен; в противном случае возвращает `False`.841842#### `is_snan(x)`843844Возвращает `True`, если *x* является сигнальным NaN; в противном случае возвращает `False`.845846#### `is_subnormal(x)`847848Возвращает `True`, если *x* субнормален; в противном случае возвращает `False`.849850#### `is_zero(x)`851852Возвращает `True`, если *x* является нулём; в противном случае возвращает `False`.853854#### `ln(x)`855856Возвращает натуральный (по основанию e) логарифм *x*.857858#### `log10(x)`859860Возвращает десятичный логарифм *x*.861862#### `logb(x)`863864Возвращает показатель степени величины старшего разряда операнда.865866#### `logical_and(x, y)`867868Применяет логическую операцию *and* к соответствующим цифрам операндов.869870#### `logical_invert(x)`871872Инвертирует все цифры в *x*.873874#### `logical_or(x, y)`875876Применяет логическую операцию *or* к соответствующим цифрам операндов.877878#### `logical_xor(x, y)`879880Применяет логическую операцию *xor* к соответствующим цифрам операндов.881882#### `max(x, y)`883884Сравнивает два числа и возвращает наибольшее.885886#### `max_mag(x, y)`887888Сравнивает числа по модулю (игнорируя знак).889890#### `min(x, y)`891892Сравнивает два числа и возвращает наименьшее.893894#### `min_mag(x, y)`895896Сравнивает числа по модулю (игнорируя знак).897898#### `minus(x)`899900Минус соответствует унарному префиксному оператору минус в Python.901902#### `multiply(x, y)`903904Возвращает произведение *x* и *y*.905906#### `next_minus(x)`907908Возвращает наибольшее представимое число, меньшее чем *x*.909910#### `next_plus(x)`911912Возвращает наименьшее представимое число, большее чем *x*.913914#### `next_toward(x, y)`915916Возвращает число, ближайшее к *x* в направлении к *y*.917918#### `normalize(x)`919920Приводит *x* к простейшей форме.921922#### `number_class(x)`923924Возвращает указание на класс *x*.925926#### `plus(x)`927928Plus соответствует унарному префиксному оператору плюс в Python. Эта операция применяет точность и округление контекста, поэтому она *не* является тождественной операцией.929930#### `power(x, y, modulo=None)`931932Возвращает `x`, возведённое в степень `y`, с приведением по модулю `modulo`, если он задан.933934С двумя аргументами вычисляется `x**y`. Если `x` отрицательно, то `y` должно быть целым. Результат будет неточным, за исключением случаев, когда `y` является целым, а результат – конечным и может быть точно выражен в 'precision' цифрах. Используется режим округления контекста. В версии Python результаты всегда правильно округлены.935936Изменено в версии 3.3: Модуль C вычисляет [`power()`](https://python-all.ru/3.4/library/decimal.html#decimal.Context.power) с помощью правильно округлённых функций [`exp()`](https://python-all.ru/3.4/library/decimal.html#decimal.Context.exp) и [`ln()`](https://python-all.ru/3.4/library/decimal.html#decimal.Context.ln). Результат хорошо определён, но только «почти всегда правильно округлён».937938С тремя аргументами вычисляется `(x**y) % modulo`. Для формы с тремя аргументами действуют следующие ограничения:939940> - все три аргумента должны быть целыми941> - `y` должно быть неотрицательным942> - по крайней мере одно из `x` или `y` должно быть ненулевым943> - `modulo` должно быть ненулевым и содержать не более 'precision' цифр944945Значение, полученное из `Context.power(x, y, modulo)`, равно значению, которое было бы получено при вычислении `(x**y) % modulo` с неограниченной точностью, но вычисляется более эффективно. Экспонента результата равна нулю независимо от экспонент `x`, `y` и `modulo`. Результат всегда точен.946947#### `quantize(x, y)`948949Возвращает значение, равное *x* (с округлением), с экспонентой *y*.950951#### `radix()`952953Просто возвращает 10, так как это Decimal, :)954955#### `remainder(x, y)`956957Возвращает остаток от целочисленного деления.958959Знак результата, если он не равен нулю, совпадает со знаком исходного делимого.960961#### `remainder_near(x, y)`962963Возвращает `x - y * n`, где *n* – целое число, ближайшее к точному значению `x / y` (если результат равен 0, его знак будет знаком *x*).964965#### `rotate(x, y)`966967Возвращает циклически сдвинутую копию *x* на *y* раз.968969#### `same_quantum(x, y)`970971Возвращает `True`, если два операнда имеют одинаковую экспоненту.972973#### `scaleb(x, y)`974975Возвращает первый операнд после добавления второго значения к его экспоненте.976977#### `shift(x, y)`978979Возвращает сдвинутую копию *x* на *y* раз.980981#### `sqrt(x)`982983Квадратный корень неотрицательного числа с точностью контекста.984985#### `subtract(x, y)`986987Возвращает разность *x* и *y*.988989#### `to_eng_string(x)`990991Преобразует число в строку, используя научную нотацию.992993#### `to_integral_exact(x)`994995Округляет до целого.996997#### `to_sci_string(x)`998999Преобразует число в строку, используя научную запись.10001001## 9.4.4. Константы10021003Константы в этом разделе имеют значение только для модуля C. Они также включены в чистую версию Python для совместимости.10041005| | 32-битный | 64-битный |1006| --- | --- | --- |1007| `decimal.``MAX_PREC` | `425000000` | `999999999999999999` |1008| `decimal.``MAX_EMAX` | `425000000` | `999999999999999999` |1009| `decimal.``MIN_EMIN` | `-425000000` | `-999999999999999999` |1010| `decimal.``MIN_ETINY` | `-849999999` | `-1999999999999999997` |10111012#### `decimal.HAVE_THREADS`10131014Значение по умолчанию – `True`. Если Python скомпилирован без поддержки потоков, C-версия автоматически отключает дорогостоящий механизм локального контекста потока. В этом случае значение равно `False`.10151016## 9.4.5. Режимы округления10171018#### `decimal.ROUND_CEILING`10191020Округление в сторону `Infinity`.10211022#### `decimal.ROUND_DOWN`10231024Округление к нулю.10251026#### `decimal.ROUND_FLOOR`10271028Округление в сторону `-Infinity`.10291030#### `decimal.ROUND_HALF_DOWN`10311032Округление до ближайшего, при связях – к нулю.10331034#### `decimal.ROUND_HALF_EVEN`10351036Округление до ближайшего, при связях – до ближайшего чётного целого.10371038#### `decimal.ROUND_HALF_UP`10391040Округление до ближайшего, при связях – от нуля.10411042#### `decimal.ROUND_UP`10431044Округление от нуля.10451046#### `decimal.ROUND_05UP`10471048Округление от нуля, если последняя цифра после округления к нулю была бы 0 или 5; в противном случае округление к нулю.10491050## 9.4.6. Сигналы10511052Сигналы представляют условия, возникающие во время вычислений. Каждый соответствует одному флагу контекста и одному включателю ловушки контекста.10531054Флаг контекста устанавливается при возникновении условия. После вычисления флаги могут быть проверены в информационных целях (например, чтобы определить, было ли вычисление точным). После проверки флагов необходимо очистить все флаги перед началом следующего вычисления.10551056Если для сигнала включён ловушечный переключатель контекста, то условие вызывает возбуждение исключения Python. Например, если установлена ловушка [`DivisionByZero`](https://python-all.ru/3.4/library/decimal.html#decimal.DivisionByZero), то при возникновении условия возбуждается исключение [`DivisionByZero`](https://python-all.ru/3.4/library/decimal.html#decimal.DivisionByZero).10571058#### `class decimal.Clamped`10591060Изменён показатель степени для соответствия ограничениям представления.10611062Обычно усечение (clamping) происходит, когда показатель степени выходит за пределы контекста `Emin` и `Emax`. Если возможно, показатель уменьшается до допустимого значения путём добавления нулей к коэффициенту.10631064#### `class decimal.DecimalException`10651066Базовый класс для остальных сигналов и подкласс [`ArithmeticError`](https://python-all.ru/3.4/library/exceptions.html#ArithmeticError).10671068#### `class decimal.DivisionByZero`10691070Сигнализирует о делении небесконечного числа на ноль.10711072Может возникнуть при делении, делении по модулю или возведении числа в отрицательную степень. Если эта ловушка не включена, возвращается `Infinity` или `-Infinity`, знак определяется входными данными вычисления.10731074#### `class decimal.Inexact`10751076Указывает, что произошло округление и результат не является точным.10771078Сигнализирует, когда при округлении были отброшены ненулевые цифры. Возвращается округлённый результат. Флаг сигнала или ловушка используется для обнаружения неточных результатов.10791080#### `class decimal.InvalidOperation`10811082Выполнена недопустимая операция.10831084Указывает на то, что была запрошена бессмысленная операция. Если ловушка не включена, возвращается `NaN`. Возможные причины включают:10851086```python1087Infinity - Infinity10880 * Infinity1089Infinity / Infinity1090x % 01091Infinity % x1092sqrt(-x) and x > 010930 ** 01094x ** (non-integer)1095x ** Infinity1096```10971098#### `class decimal.Overflow`10991100Числовое переполнение.11011102Указывает, что показатель степени превышает `Emax` после округления. Если ловушка не включена, результат зависит от режима округления: либо округление внутрь до наибольшего представимого конечного числа, либо округление наружу до `Infinity`. В любом случае также сигнализируются [`Inexact`](https://python-all.ru/3.4/library/decimal.html#decimal.Inexact) и [`Rounded`](https://python-all.ru/3.4/library/decimal.html#decimal.Rounded).11031104#### `class decimal.Rounded`11051106Произошло округление, хотя, возможно, информация не была потеряна.11071108Срабатывает при каждом округлении, отбрасывающем цифры, даже если эти цифры нулевые (например, при округлении `5.00` до `5.0`). Если не перехвачено, возвращает результат без изменений. Этот сигнал используется для обнаружения потери значащих цифр.11091110#### `class decimal.Subnormal`11111112Exponent was lower than `Emin` prior to rounding.11131114Возникает, когда результат операции является субнормальным (экспонента слишком мала). Если не перехвачено, возвращает результат без изменений.11151116#### `class decimal.Underflow`11171118Числовое исчерпание с округлением результата до нуля.11191120Occurs when a subnormal result is pushed to zero by rounding. [`Inexact`](https://python-all.ru/3.4/library/decimal.html#decimal.Inexact) and [`Subnormal`](https://python-all.ru/3.4/library/decimal.html#decimal.Subnormal) are also signaled.11211122#### `class decimal.FloatOperation`11231124Включает более строгую семантику смешивания чисел с плавающей запятой и десятичных чисел.11251126If the signal is not trapped (default), mixing floats and Decimals is permitted in the [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) constructor, [`create_decimal()`](https://python-all.ru/3.4/library/decimal.html#decimal.Context.create_decimal) and all comparison operators. Both conversion and comparisons are exact. Any occurrence of a mixed operation is silently recorded by setting [`FloatOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.FloatOperation) in the context flags. Explicit conversions with [`from_float()`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal.from_float) or [`create_decimal_from_float()`](https://python-all.ru/3.4/library/decimal.html#decimal.Context.create_decimal_from_float) do not set the flag.11271128Otherwise (the signal is trapped), only equality comparisons and explicit conversions are silent. All other mixed operations raise [`FloatOperation`](https://python-all.ru/3.4/library/decimal.html#decimal.FloatOperation).11291130В следующей таблице приведена иерархия сигналов:11311132```python1133exceptions.ArithmeticError(exceptions.Exception)1134 DecimalException1135 Clamped1136 DivisionByZero(DecimalException, exceptions.ZeroDivisionError)1137 Inexact1138 Overflow(Inexact, Rounded)1139 Underflow(Inexact, Rounded, Subnormal)1140 InvalidOperation1141 Rounded1142 Subnormal1143 FloatOperation(DecimalException, exceptions.TypeError)1144```11451146## 9.4.7. Замечания по числам с плавающей запятой11471148### 9.4.7.1. Уменьшение ошибки округления с помощью повышенной точности11491150Использование десятичной арифметики с плавающей запятой устраняет ошибку десятичного представления (позволяя точно представить `0.1`); однако некоторые операции всё ещё могут приводить к ошибке округления, когда ненулевые цифры превышают фиксированную точность.11511152Влияние ошибки округления может усиливаться при сложении или вычитании почти компенсирующих друг друга величин, что приводит к потере значимости. Кнут приводит два поучительных примера, в которых округлённая арифметика с плавающей точкой с недостаточной точностью приводит к нарушению ассоциативного и дистрибутивного свойств сложения:11531154```python1155# Примеры из Seminumerical Algorithms, раздел 4.2.2.1156>>> from decimal import Decimal, getcontext1157>>> getcontext().prec = 811581159>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')1160>>> (u + v) + w1161Decimal('9.5111111')1162>>> u + (v + w)1163Decimal('10')11641165>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')1166>>> (u*v) + (u*w)1167Decimal('0.01')1168>>> u * (v+w)1169Decimal('0.0060000')1170```11711172The [`decimal`](https://python-all.ru/3.4/library/decimal.html#module-decimal) module makes it possible to restore the identities by expanding the precision sufficiently to avoid loss of significance:11731174```python1175>>> getcontext().prec = 201176>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')1177>>> (u + v) + w1178Decimal('9.51111111')1179>>> u + (v + w)1180Decimal('9.51111111')1181>>>1182>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')1183>>> (u*v) + (u*w)1184Decimal('0.0060000')1185>>> u * (v+w)1186Decimal('0.0060000')1187```11881189### 9.4.7.2. Особые значения11901191The number system for the [`decimal`](https://python-all.ru/3.4/library/decimal.html#module-decimal) module provides special values including `NaN`, `sNaN`, `-Infinity`, `Infinity`, and two zeros, `+0` and `-0`.11921193Infinities can be constructed directly with: `Decimal('Infinity')`. Also, they can arise from dividing by zero when the [`DivisionByZero`](https://python-all.ru/3.4/library/decimal.html#decimal.DivisionByZero) signal is not trapped. Likewise, when the [`Overflow`](https://python-all.ru/3.4/library/decimal.html#decimal.Overflow) signal is not trapped, infinity can result from rounding beyond the limits of the largest representable number.11941195Бесконечности являются знаковыми (аффинными) и могут использоваться в арифметических операциях, где они трактуются как очень большие неопределённые числа. Например, прибавление константы к бесконечности даёт другой бесконечный результат.11961197Some operations are indeterminate and return `NaN`, or if the [`InvalidOperation`](https://python-all.ru/3.4/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.11981199A 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.12001201The 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.4/library/constants.html#False) (even when doing `Decimal('NaN')==Decimal('NaN')`), while a test for inequality always returns [`True`](https://python-all.ru/3.4/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.4/library/decimal.html#decimal.InvalidOperation) signal if either operand is a `NaN`, and return [`False`](https://python-all.ru/3.4/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.12021203Знаковые нули могут возникать в результате вычислений, приводящих к исчерпанию. Они сохраняют знак, который получился бы, если бы вычисления выполнялись с большей точностью. Поскольку их величина равна нулю, положительный и отрицательный нули считаются равными, а их знак является информационным.12041205Помимо двух знаковых нулей, которые различны, но равны, существуют различные представления нуля с разной точностью, но эквивалентные по значению. К этому нужно немного привыкнуть. Для глаза, привыкшего к нормализованным представлениям чисел с плавающей точкой, не сразу очевидно, что следующее вычисление возвращает значение, равное нулю:12061207```python1208>>> 1 / Decimal('Infinity')1209Decimal('0E-1000026')1210```12111212## 9.4.8. Работа с потоками12131214The [`getcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.getcontext) function accesses a different [`Context`](https://python-all.ru/3.4/library/decimal.html#decimal.Context) object for each thread. Having separate thread contexts means that threads may make changes (such as `getcontext().prec=10`) without interfering with other threads.12151216Likewise, the [`setcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.setcontext) function automatically assigns its target to the current thread.12171218If [`setcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.setcontext) has not been called before [`getcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.getcontext), then [`getcontext()`](https://python-all.ru/3.4/library/decimal.html#decimal.getcontext) will automatically create a new context for use in the current thread.12191220The 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.4/library/decimal.html#decimal.getcontext). For example:12211222```python1223# Установить глобальные настройки по умолчанию для всех потоков, которые будут запущены1224DefaultContext.prec = 121225DefaultContext.rounding = ROUND_DOWN1226DefaultContext.traps = ExtendedContext.traps.copy()1227DefaultContext.traps[InvalidOperation] = 11228setcontext(DefaultContext)12291230# После этого потоки можно запускать1231t1.start()1232t2.start()1233t3.start()1234 . . .1235```12361237## 9.4.9. Рецепты12381239Here are a few recipes that serve as utility functions and that demonstrate ways to work with the [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal) class:12401241```python1242def moneyfmt(value, places=2, curr='', sep=',', dp='.',1243 pos='', neg='-', trailneg=''):1244 """Преобразовать Decimal в строку, отформатированную как денежная сумма.12451246 places: обязательное количество знаков после десятичной точки1247 curr: необязательный символ валюты перед знаком (может быть пустым)1248 sep: необязательный разделитель групп (запятая, точка, пробел или пусто)1249 dp: указатель десятичной точки (запятая или точка)1250 указывать пустым только при places=01251 pos: необязательный знак для положительных чисел: '+', пробел или пусто1252 neg: необязательный знак для отрицательных чисел: '-', '(', пробел или пусто1253 trailneg:необязательный завершающий знак минуса: '-', ')', пробел или пусто12541255 >>> d = Decimal('-1234567.8901')1256 >>> moneyfmt(d, curr='$')1257 '-$1,234,567.89'1258 >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')1259 '1.234.568-'1260 >>> moneyfmt(d, curr='$', neg='(', trailneg=')')1261 '($1,234,567.89)'1262 >>> moneyfmt(Decimal(123456789), sep=' ')1263 '123 456 789.00'1264 >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')1265 '<0.02>'12661267 """1268 q = Decimal(10) ** -places # 2 знака после запятой --> '0.01'1269 sign, digits, exp = value.quantize(q).as_tuple()1270 result = []1271 digits = list(map(str, digits))1272 build, next = result.append, digits.pop1273 if sign:1274 build(trailneg)1275 for i in range(places):1276 build(next() if digits else '0')1277 if places:1278 build(dp)1279 if not digits:1280 build('0')1281 i = 01282 while digits:1283 build(next())1284 i += 11285 if i == 3 and digits:1286 i = 01287 build(sep)1288 build(curr)1289 build(neg if sign else pos)1290 return ''.join(reversed(result))12911292def pi():1293 """Вычислить число Пи с текущей точностью.12941295 >>> print(pi())1296 3.14159265358979323846264338312971298 """1299 getcontext().prec += 2 # дополнительные цифры для промежуточных шагов1300 three = Decimal(3) # подставить "three=3.0" вместо обычных чисел с плавающей точкой1301 lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 241302 while s != lasts:1303 lasts = s1304 n, na = n+na, na+81305 d, da = d+da, da+321306 t = (t * n) / d1307 s += t1308 getcontext().prec -= 21309 return +s # унарный плюс применяет новую точность13101311def exp(x):1312 """Возвращает e, возведённое в степень x. Тип результата соответствует типу входного значения.13131314 >>> print(exp(Decimal(1)))1315 2.7182818284590452353602874711316 >>> print(exp(Decimal(2)))1317 7.3890560989306502272304274611318 >>> print(exp(2.0))1319 7.389056098931320 >>> print(exp(2+0j))1321 (7.38905609893+0j)13221323 """1324 getcontext().prec += 21325 i, lasts, s, fact, num = 0, 0, 1, 1, 11326 while s != lasts:1327 lasts = s1328 i += 11329 fact *= i1330 num *= x1331 s += num / fact1332 getcontext().prec -= 21333 return +s13341335def cos(x):1336 """Возвращает косинус x, измеренного в радианах.13371338 Аппроксимация рядом Тейлора даёт наилучший результат при малых значениях x.1339 Для больших значений сначала вычислите x = x % (2 * pi).13401341 >>> print(cos(Decimal('0.5')))1342 0.87758256189037271611628158261343 >>> print(cos(0.5))1344 0.877582561891345 >>> print(cos(0.5+0j))1346 (0.87758256189+0j)13471348 """1349 getcontext().prec += 21350 i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 11351 while s != lasts:1352 lasts = s1353 i += 21354 fact *= i * (i-1)1355 num *= x * x1356 sign *= -11357 s += num / fact * sign1358 getcontext().prec -= 21359 return +s13601361def sin(x):1362 """Возвращает синус угла x, заданного в радианах.13631364 Аппроксимация рядом Тейлора даёт наилучший результат при малых значениях x.1365 Для больших значений сначала вычислите x = x % (2 * pi).13661367 >>> print(sin(Decimal('0.5')))1368 0.47942553860420300027328793521369 >>> print(sin(0.5))1370 0.4794255386041371 >>> print(sin(0.5+0j))1372 (0.479425538604+0j)13731374 """1375 getcontext().prec += 21376 i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 11377 while s != lasts:1378 lasts = s1379 i += 21380 fact *= i * (i-1)1381 num *= x * x1382 sign *= -11383 s += num / fact * sign1384 getcontext().prec -= 21385 return +s1386```13871388## 9.4.10. Часто задаваемые вопросы о Decimal13891390Q. It is cumbersome to type `decimal.Decimal('1234.5')`. Is there a way to minimize typing when using the interactive interpreter?13911392Ответ. Некоторые пользователи сокращают конструктор до одной буквы:13931394```python1395>>> D = decimal.Decimal1396>>> D('1.23') + D('3.45')1397Decimal('4.68')1398```13991400Вопрос. В приложении с фиксированной запятой с двумя десятичными знаками некоторые входные данные имеют много знаков и нуждаются в округлении. Другие не должны содержать лишних цифр и требуют проверки. Какие методы следует использовать?14011402A. The `quantize()` method rounds to a fixed number of decimal places. If the [`Inexact`](https://python-all.ru/3.4/library/decimal.html#decimal.Inexact) trap is set, it is also useful for validation:14031404```python1405>>> TWOPLACES = Decimal(10) ** -2 # то же, что Decimal('0.01')1406```14071408```python1409>>> # Округлить до двух знаков1410>>> Decimal('3.214').quantize(TWOPLACES)1411Decimal('3.21')1412```14131414```python1415>>> # Проверка, что число не выходит за пределы двух знаков1416>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))1417Decimal('3.21')1418```14191420```python1421>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))1422Traceback (most recent call last):1423 ...1424Inexact: None1425```14261427Вопрос. Получив корректные входные данные с двумя знаками, как поддерживать этот инвариант во всём приложении?14281429A. 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:14301431```python1432>>> a = Decimal('102.72') # Начальные значения чисел с фиксированной точкой1433>>> b = Decimal('3.17')1434>>> a + b # Сложение сохраняет фиксированную точку1435Decimal('105.89')1436>>> a - b1437Decimal('99.55')1438>>> a * 42 # Умножение на целое число – тоже1439Decimal('4314.24')1440>>> (a * b).quantize(TWOPLACES) # Результат умножения на нецелое число нужно квантовать1441Decimal('325.62')1442>>> (b / a).quantize(TWOPLACES) # И квантовать результат деления1443Decimal('0.03')1444```14451446In developing fixed-point applications, it is convenient to define functions to handle the `quantize()` step:14471448```python1449>>> def mul(x, y, fp=TWOPLACES):1450... return (x * y).quantize(fp)1451>>> def div(x, y, fp=TWOPLACES):1452... return (x / y).quantize(fp)1453```14541455```python1456>>> mul(a, b) # Автоматически сохранять фиксированную точку1457Decimal('325.62')1458>>> div(b, a)1459Decimal('0.03')1460```14611462Q. 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?14631464A. The `normalize()` method maps all equivalent values to a single representative:14651466```python1467>>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())1468>>> [v.normalize() for v in values]1469[Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]1470```14711472Вопрос. Некоторые значения decimal всегда выводятся в экспоненциальной записи. Есть ли способ получить неэкспоненциальное представление?14731474A. 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.14751476Если приложению не важно отслеживать значимость, можно легко удалить экспоненту и хвостовые нули, потеряв значимость, но сохранив значение:14771478```python1479>>> def remove_exponent(d):1480... return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()1481```14821483```python1484>>> remove_exponent(Decimal('5E+3'))1485Decimal('5000')1486```14871488Q. Is there a way to convert a regular float to a [`Decimal`](https://python-all.ru/3.4/library/decimal.html#decimal.Decimal)?14891490A. Да, любое двоичное число с плавающей точкой может быть точно выражено как Decimal, хотя для точного преобразования может потребоваться больше точности, чем подсказывает интуиция:14911492```python1493>>> Decimal(math.pi)1494Decimal('3.141592653589793115997963468544185161590576171875')1495```14961497Вопрос. В сложном вычислении как я могу убедиться, что не получил ложный результат из-за недостаточной точности или аномалий округления?14981499Ответ. Модуль decimal упрощает проверку результатов. Рекомендуется перезапускать вычисления с большей точностью и различными режимами округления. Сильно различающиеся результаты указывают на недостаточную точность, проблемы с режимом округления, плохо обусловленные входные данные или численно неустойчивый алгоритм.15001501Вопрос. Я заметил, что точность контекста применяется к результатам операций, но не к входным данным. Есть ли что-то, на что следует обращать внимание при смешивании значений разной точности?15021503Ответ. Да. Принцип заключается в том, что все значения считаются точными, как и арифметические операции с ними. Округляются только результаты. Преимущество для входных данных в том, что «что ввёл, то и получил». Недостаток в том, что результаты могут выглядеть странно, если забыть, что входные данные не округлены:15041505```python1506>>> getcontext().prec = 31507>>> Decimal('3.104') + Decimal('2.104')1508Decimal('5.21')1509>>> Decimal('3.104') + Decimal('0.000') + Decimal('2.104')1510Decimal('5.20')1511```15121513Решение – либо увеличить точность, либо принудительно округлить входные данные с помощью унарного плюса:15141515```python1516>>> getcontext().prec = 31517>>> +Decimal('1.23456789') # Унарный плюс вызывает округление1518Decimal('1.23')1519```15201521Alternatively, inputs can be rounded upon creation using the [`Context.create_decimal()`](https://python-all.ru/3.4/library/decimal.html#decimal.Context.create_decimal) method:15221523```python1524>>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')1525Decimal('1.2345')1526```1527