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

decimal.md

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

1> **Источник:** https://python-all.ru/2.7/library/decimal.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 9.4. [`decimal`](https://python-all.ru/2.7/library/decimal.html#module-decimal) – десятичная арифметика с фиксированной и плавающей точкой89Новое в версии 2.4.1011Модуль [`decimal`](https://python-all.ru/2.7/library/decimal.html#module-decimal) поддерживает десятичную арифметику с плавающей точкой. Он даёт несколько преимуществ по сравнению с типом данных [`float`](https://python-all.ru/2.7/library/functions.html#float):1213- Decimal «основан на модели с плавающей запятой, разработанной с учетом человеческих потребностей, и имеет первостепенный руководящий принцип – компьютеры должны обеспечивать арифметику, работающую так же, как арифметика, которой люди учатся в школе». – отрывок из спецификации десятичной арифметики.14- Десятичные числа можно представить точно. В отличие от них, такие числа, как `1.1` и `2.2`, не имеют точного представления в двоичной плавающей арифметике. Конечные пользователи обычно не ожидают, что `1.1 + 2.2` отобразится как `3.3000000000000003`, как это происходит с двоичной плавающей точкой.15- Точность распространяется и на арифметику. В десятичной арифметике с плавающей запятой `0.1 + 0.1 + 0.1 - 0.3` точно равно нулю. В двоичной арифметике с плавающей запятой результат равен `5.5511151231257827e-017`. Хотя он близок к нулю, эти различия препятствуют надёжной проверке на равенство и могут накапливаться. По этой причине десятичная арифметика предпочтительна в бухгалтерских приложениях, где существуют строгие инварианты равенства.16- Модуль decimal включает понятие значащих разрядов, так что `1.30 + 1.20` равно `2.50`. Замыкающий ноль сохраняется для указания значимости. Это стандартное представление для финансовых приложений. Для умножения «школьный» подход использует все цифры множителей. Например, `1.3 * 1.2` даёт `1.56`, а `1.30 * 1.20` даёт `1.5600`.17- В отличие от аппаратно реализованной двоичной арифметики с плавающей запятой, модуль decimal имеет настраиваемую точность (по умолчанию 28 знаков), которая может быть сколь угодно большой для данной задачи:1819  ```python20  >>> from decimal import *21  >>> getcontext().prec = 622  >>> Decimal(1) / Decimal(7)23  Decimal('0.142857')24  >>> getcontext().prec = 2825  >>> Decimal(1) / Decimal(7)26  Decimal('0.1428571428571428571428571429')27  ```28- Как двоичная, так и десятичная арифметика с плавающей запятой реализованы в соответствии с опубликованными стандартами. В то время как встроенный тип float предоставляет лишь скромную часть своих возможностей, модуль decimal предоставляет все необходимые части стандарта. При необходимости программист имеет полный контроль над округлением и обработкой сигналов. Это включает возможность принудительного точного выполнения арифметики с помощью исключений для блокировки любых неточных операций.29- Модуль decimal был разработан для поддержки «без каких-либо предпочтений как точной неокруглённой десятичной арифметики (иногда называемой арифметикой с фиксированной запятой), так и округлённой арифметики с плавающей запятой.» – выдержка из спецификации десятичной арифметики.3031Дизайн модуля сосредоточен на трёх концепциях: десятичное число, контекст арифметики и сигналы.3233Десятичное число неизменяемо. Оно имеет знак, цифры коэффициента и показатель степени. Для сохранения значимости цифры коэффициента не отбрасывают замыкающие нули. Десятичные числа также включают специальные значения, такие как `Infinity`, `-Infinity` и `NaN`. Стандарт также различает `-0` и `+0`.3435Контекст арифметики – это окружение, задающее точность, правила округления, ограничения на показатели степени, флаги, указывающие на результаты операций, и активаторы ловушек, которые определяют, обрабатываются ли сигналы как исключения. Варианты округления включают `ROUND_CEILING`, `ROUND_DOWN`, `ROUND_FLOOR`, `ROUND_HALF_DOWN`, `ROUND_HALF_EVEN`, `ROUND_HALF_UP`, `ROUND_UP` и `ROUND_05UP`.3637Сигналы – это группы исключительных ситуаций, возникающих в ходе вычислений. В зависимости от потребностей приложения сигналы можно игнорировать, рассматривать как информацию или обрабатывать как исключения. Сигналы в модуле decimal: [`Clamped`](https://python-all.ru/2.7/library/decimal.html#decimal.Clamped), [`InvalidOperation`](https://python-all.ru/2.7/library/decimal.html#decimal.InvalidOperation), [`DivisionByZero`](https://python-all.ru/2.7/library/decimal.html#decimal.DivisionByZero), [`Inexact`](https://python-all.ru/2.7/library/decimal.html#decimal.Inexact), [`Rounded`](https://python-all.ru/2.7/library/decimal.html#decimal.Rounded), [`Subnormal`](https://python-all.ru/2.7/library/decimal.html#decimal.Subnormal), [`Overflow`](https://python-all.ru/2.7/library/decimal.html#decimal.Overflow) и [`Underflow`](https://python-all.ru/2.7/library/decimal.html#decimal.Underflow).3839Для каждого сигнала существует флаг и активатор ловушки. Когда сигнал обнаруживается, его флаг устанавливается в единицу, затем, если активатор ловушки установлен в единицу, возбуждается исключение. Флаги сохраняют состояние, поэтому пользователю необходимо сбрасывать их перед мониторингом вычислений.4041> **См. также**42>43> - Спецификация общей десятичной арифметики IBM, [Общая спецификация десятичной арифметики](https://python-all.ru/2.7/library/decimal.html).4445## 9.4.1. Краткое руководство4647Обычно работа с десятичными числами начинается с импорта модуля decimal, просмотра текущего контекста с помощью [`getcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.getcontext) и, при необходимости, установки новых значений точности, округления или включённых ловушек:4849```python50>>> from decimal import *51>>> getcontext()52Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,53        capitals=1, flags=[], traps=[Overflow, DivisionByZero,54        InvalidOperation])5556>>> getcontext().prec = 7       # Установить новую точность57```5859Экземпляры Decimal можно создавать из целых чисел, строк, чисел с плавающей точкой или кортежей. Создание из целого числа или числа с плавающей точкой выполняет точное преобразование значения этого целого или числа с плавающей точкой. Десятичные числа включают специальные значения, такие как `NaN` («не число»), положительная и отрицательная `Infinity`, а также `-0`.6061```python62>>> getcontext().prec = 2863>>> Decimal(10)64Decimal('10')65>>> Decimal('3.14')66Decimal('3.14')67>>> Decimal(3.14)68Decimal('3.140000000000000124344978758017532527446746826171875')69>>> Decimal((0, (3, 1, 4), -2))70Decimal('3.14')71>>> Decimal(str(2.0 ** 0.5))72Decimal('1.41421356237')73>>> Decimal(2) ** Decimal('0.5')74Decimal('1.414213562373095048801688724')75>>> Decimal('NaN')76Decimal('NaN')77>>> Decimal('-Infinity')78Decimal('-Infinity')79```8081Значимость нового Decimal определяется исключительно количеством введённых цифр. Точность контекста и округление вступают в силу только во время арифметических операций.8283```pycon84>>> getcontext().prec = 685>>> Decimal('3.0')86Decimal('3.0')87>>> Decimal('3.1415926535')88Decimal('3.1415926535')89>>> Decimal('3.1415926535') + Decimal('2.7182818285')90Decimal('5.85987')91>>> getcontext().rounding = ROUND_UP92>>> Decimal('3.1415926535') + Decimal('2.7182818285')93Decimal('5.85988')94```9596Десятичные числа хорошо взаимодействуют с остальной частью Python. Вот небольшой пример разнообразия десятичной арифметики с плавающей точкой:9798```pycon99>>> data = map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split())100>>> max(data)101Decimal('9.25')102>>> min(data)103Decimal('0.03')104>>> sorted(data)105[Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),106 Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]107>>> sum(data)108Decimal('19.29')109>>> a,b,c = data[:3]110>>> str(a)111'1.34'112>>> float(a)1131.34114>>> round(a, 1)     # round() сначала преобразует в двоичное число с плавающей точкой.1151.3116>>> int(a)1171118>>> a * 5119Decimal('6.70')120>>> a * b121Decimal('2.5058')122>>> c % a123Decimal('0.77')124```125126Также некоторые математические функции доступны для Decimal:127128```python129>>> getcontext().prec = 28130>>> Decimal(2).sqrt()131Decimal('1.414213562373095048801688724')132>>> Decimal(1).exp()133Decimal('2.718281828459045235360287471')134>>> Decimal('10').ln()135Decimal('2.302585092994045684017991455')136>>> Decimal('10').log10()137Decimal('1')138```139140Метод `quantize()` округляет число до заданного показателя степени. Этот метод полезен для финансовых приложений, которые часто округляют результаты до фиксированного количества знаков:141142```python143>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)144Decimal('7.32')145>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)146Decimal('8')147```148149Как показано выше, функция [`getcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.getcontext) обращается к текущему контексту и позволяет изменять настройки. Такой подход удовлетворяет потребности большинства приложений.150151Для более сложных задач может быть полезно создавать альтернативные контексты с помощью конструктора Context(). Чтобы сделать альтернативный контекст активным, используйте функцию [`setcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.setcontext).152153В соответствии со стандартом модуль [`decimal`](https://python-all.ru/2.7/library/decimal.html#module-decimal) предоставляет два готовых к использованию стандартных контекста: [`BasicContext`](https://python-all.ru/2.7/library/decimal.html#decimal.BasicContext) и [`ExtendedContext`](https://python-all.ru/2.7/library/decimal.html#decimal.ExtendedContext). Первый особенно полезен для отладки, так как многие ловушки в нём включены:154155```pycon156>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)157>>> setcontext(myothercontext)158>>> Decimal(1) / Decimal(7)159Decimal('0.142857142857142857142857142857142857142857142857142857142857')160161>>> ExtendedContext162Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,163        capitals=1, flags=[], traps=[])164>>> setcontext(ExtendedContext)165>>> Decimal(1) / Decimal(7)166Decimal('0.142857143')167>>> Decimal(42) / Decimal(0)168Decimal('Infinity')169170>>> setcontext(BasicContext)171>>> Decimal(42) / Decimal(0)172Traceback (most recent call last):173  File "<pyshell#143>", line 1, in -toplevel-174    Decimal(42) / Decimal(0)175DivisionByZero: x / 0176```177178Контексты также имеют флаги сигналов для мониторинга исключительных ситуаций, возникающих во время вычислений. Флаги остаются установленными до явного сброса, поэтому лучше всего сбрасывать флаги перед каждой группой контролируемых вычислений с помощью метода `clear_flags()`.179180```python181>>> setcontext(ExtendedContext)182>>> getcontext().clear_flags()183>>> Decimal(355) / Decimal(113)184Decimal('3.14159292')185>>> getcontext()186Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,187        capitals=1, flags=[Rounded, Inexact], traps=[])188```189190Запись *flags* показывает, что рациональное приближение к `Pi` было округлено (цифры, выходящие за пределы точности контекста, были отброшены), а результат неточен (некоторые отброшенные цифры были ненулевыми).191192Отдельные ловушки настраиваются с помощью словаря в поле `traps` контекста:193194```pycon195>>> setcontext(ExtendedContext)196>>> Decimal(1) / Decimal(0)197Decimal('Infinity')198>>> getcontext().traps[DivisionByZero] = 1199>>> Decimal(1) / Decimal(0)200Traceback (most recent call last):201  File "<pyshell#112>", line 1, in -toplevel-202    Decimal(1) / Decimal(0)203DivisionByZero: x / 0204```205206Большинство программ настраивают текущий контекст только один раз, в начале программы. И во многих приложениях данные преобразуются в [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) с помощью одного приведения типа внутри цикла. После установки контекста и создания десятичных чисел основная часть программы манипулирует данными так же, как и с другими числовыми типами Python.207208## 9.4.2. Объекты Decimal209210#### `class decimal.Decimal([value[, context]])`211212Создаёт новый объект [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) на основе *value*.213214*value* может быть целым числом, строкой, кортежем, [`float`](https://python-all.ru/2.7/library/functions.html#float) или другим объектом [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal). Если *value* не указан, возвращается `Decimal('0')`. Если *value* – строка, то после удаления начальных и конечных пробелов она должна соответствовать синтаксису десятичной числовой строки:215216```python217sign           ::=  '+' | '-'218digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'219indicator      ::=  'e' | 'E'220digits         ::=  digit [digit]...221decimal-part   ::=  digits '.' [digits] | ['.'] digits222exponent-part  ::=  indicator [sign] digits223infinity       ::=  'Infinity' | 'Inf'224nan            ::=  'NaN' [digits] | 'sNaN' [digits]225numeric-value  ::=  decimal-part [exponent-part] | infinity226numeric-string ::=  [sign] numeric-value | [sign] nan227```228229Если *value* является строкой Unicode, то в местах, где выше указано `digit`, также допускаются другие десятичные цифры Unicode. К ним относятся десятичные цифры из различных других алфавитов (например, арабо-индийские и деванагари), а также полноширинные цифры от `u'\uff10'` до `u'\uff19'`.230231Если *value* является [`tuple`](https://python-all.ru/2.7/library/functions.html#tuple), он должен содержать три компонента: знак (`0` для положительного или `1` для отрицательного), [`tuple`](https://python-all.ru/2.7/library/functions.html#tuple) цифр и целочисленный показатель степени. Например, `Decimal((0, (1, 4, 1, 4), -3))` возвращает `Decimal('1.414')`.232233Если *value* – это [`float`](https://python-all.ru/2.7/library/functions.html#float), двоичное значение с плавающей точкой без потерь преобразуется в точный десятичный эквивалент. Для такого преобразования часто требуется 53 или более знаков точности. Например, `Decimal(float('1.1'))` преобразуется в `Decimal('1.100000000000000088817841970012523233890533447265625')`.234235Точность *context* не влияет на количество сохраняемых цифр. Оно определяется исключительно количеством цифр в *value*. Например, `Decimal('3.00000')` сохраняет все пять нулей, даже если точность контекста равна всего трём.236237Назначение аргумента *context* – определять, что делать, если *value* является некорректной строкой. Если контекст перехватывает [`InvalidOperation`](https://python-all.ru/2.7/library/decimal.html#decimal.InvalidOperation), возбуждается исключение; в противном случае конструктор возвращает новый Decimal со значением `NaN`.238239После создания объекты [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) неизменяемы.240241Изменено в версии 2.6: при создании экземпляра Decimal из строки допускаются начальные и конечные пробельные символы.242243Изменено в версии 2.7: аргумент конструктора теперь может быть экземпляром [`float`](https://python-all.ru/2.7/library/functions.html#float).244245Объекты десятичной арифметики с плавающей точкой разделяют многие свойства с другими встроенными числовыми типами, такими как [`float`](https://python-all.ru/2.7/library/functions.html#float) и [`int`](https://python-all.ru/2.7/library/functions.html#int). Применимы все обычные математические операции и специальные методы. Кроме того, десятичные объекты можно копировать, сериализовать, выводить, использовать в качестве ключей словаря, элементов множества, сравнивать, сортировать и преобразовывать в другой тип (например, [`float`](https://python-all.ru/2.7/library/functions.html#float) или [`long`](https://python-all.ru/2.7/library/functions.html#long)).246247Существуют небольшие различия между арифметикой над объектами Decimal и арифметикой над целыми числами и числами с плавающей запятой. Когда оператор остатка `%` применяется к объектам Decimal, знак результата совпадает со знаком *dividend*, а не со знаком делителя:248249```python250>>> (-7) % 42511252>>> Decimal(-7) % Decimal(4)253Decimal('-3')254```255256Оператор целочисленного деления `//` ведёт себя аналогично: возвращает целую часть истинного частного (отсечение к нулю), а не его пол, чтобы сохранить обычное тождество `x == (x // y) * y + x % y`:257258```python259>>> -7 // 4260-2261>>> Decimal(-7) // Decimal(4)262Decimal('-1')263```264265Операторы `%` и `//` реализуют операции `remainder` и `divide-integer` (соответственно), как описано в спецификации.266267Объекты Decimal обычно нельзя комбинировать с числами с плавающей точкой в арифметических операциях: например, попытка сложить [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) и [`float`](https://python-all.ru/2.7/library/functions.html#float) вызовет [`TypeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.TypeError). Из этого правила есть одно исключение: операторы сравнения Python можно использовать для сравнения экземпляра [`float`](https://python-all.ru/2.7/library/functions.html#float) `x` с экземпляром [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) `y`. Без этого исключения сравнения между экземплярами [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) и [`float`](https://python-all.ru/2.7/library/functions.html#float) следовали бы общим правилам сравнения объектов разных типов, описанным в разделе [Выражения](https://python-all.ru/2.7/reference/expressions.html#expressions) справочного руководства, что приводило бы к запутанным результатам.268269Изменено в версии 2.7: сравнение между экземпляром [`float`](https://python-all.ru/2.7/library/functions.html#float) `x` и экземпляром [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) `y` теперь возвращает результат на основе значений `x` и `y`. В более ранних версиях `x < y` возвращало одинаковый (произвольный) результат для любого экземпляра [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) `x` и любого экземпляра [`float`](https://python-all.ru/2.7/library/functions.html#float) `y`.270271В дополнение к стандартным числовым свойствам десятичные объекты с плавающей точкой также имеют ряд специализированных методов:272273#### `adjusted()`274275Возвращает скорректированный показатель степени после сдвига самых правых цифр коэффициента до тех пор, пока не останется только ведущая цифра: `Decimal('321e+5').adjusted()` возвращает семь. Используется для определения положения самой значащей цифры относительно десятичной точки.276277#### `as_tuple()`278279Возвращает [именованный кортеж](https://python-all.ru/2.7/glossary.html#term-named-tuple) представление числа: `DecimalTuple(sign, digits, exponent)`.280281Изменено в версии 2.6: используется именованный кортеж.282283#### `canonical()`284285Возвращает каноническую кодировку аргумента. В настоящее время кодировка экземпляра [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) всегда канонична, поэтому эта операция возвращает свой аргумент без изменений.286287Новое в версии 2.6.288289#### `compare(other[, context])`290291Сравнивает значения двух экземпляров Decimal. Эта операция ведёт себя так же, как обычный метод сравнения [`__cmp__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__cmp__), за исключением того, что [`compare()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.compare) возвращает экземпляр Decimal, а не целое число, и если хотя бы один операнд является NaN, то результат будет NaN:292293```python294a or b is a NaN ==> Decimal('NaN')295a < b           ==> Decimal('-1')296a == b          ==> Decimal('0')297a > b           ==> Decimal('1')298```299300#### `compare_signal(other[, context])`301302Эта операция идентична методу [`compare()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.compare), за исключением того, что все NaN сигнализируют. То есть, если ни один операнд не является сигнальным NaN, то любой тихий NaN обрабатывается так, как если бы он был сигнальным NaN.303304Новое в версии 2.6.305306#### `compare_total(other)`307308Сравнивает два операнда, используя их абстрактное представление, а не числовое значение. Аналогично методу [`compare()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.compare), но результат задаёт полный порядок на экземплярах [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal). Два экземпляра [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) с одинаковым числовым значением, но разными представлениями, в этом порядке считаются неравными:309310```python311>>> Decimal('12.0').compare_total(Decimal('12'))312Decimal('-1')313```314315Тихие и сигнальные NaN также включены в полный порядок. Результат этой функции равен `Decimal('0')`, если оба операнда имеют одинаковое представление, `Decimal('-1')`, если первый операнд меньше второго в полном порядке, и `Decimal('1')`, если первый операнд больше второго. См. спецификацию для подробностей полного порядка.316317Новое в версии 2.6.318319#### `compare_total_mag(other)`320321Сравнивает два операнда, используя их абстрактное представление, а не их значение, как в [`compare_total()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.compare_total), но игнорируя знак каждого операнда. `x.compare_total_mag(y)` эквивалентно `x.copy_abs().compare_total(y.copy_abs())`.322323Новое в версии 2.6.324325#### `conjugate()`326327Просто возвращает self; этот метод существует только для соответствия спецификации Decimal.328329Новое в версии 2.6.330331#### `copy_abs()`332333Возвращает абсолютное значение аргумента. Эта операция не зависит от контекста и является тихой: флаги не изменяются и округление не выполняется.334335Новое в версии 2.6.336337#### `copy_negate()`338339Возвращает отрицание аргумента. Эта операция не зависит от контекста и является тихой: флаги не изменяются и округление не выполняется.340341Новое в версии 2.6.342343#### `copy_sign(other)`344345Возвращает копию первого операнда со знаком, установленным таким же, как знак второго операнда. Например:346347```python348>>> Decimal('2.3').copy_sign(Decimal('-1.5'))349Decimal('-2.3')350```351352Эта операция не зависит от контекста и является тихой: никакие флаги не изменяются и округление не выполняется.353354Новое в версии 2.6.355356#### `exp([context])`357358Возвращает значение (натуральной) показательной функции `e**x` для заданного числа. Результат корректно округляется с использованием режима округления `ROUND_HALF_EVEN`.359360```python361>>> Decimal(1).exp()362Decimal('2.718281828459045235360287471')363>>> Decimal(321).exp()364Decimal('2.561702493119680037517373933E+139')365```366367Новое в версии 2.6.368369#### `from_float(f)`370371Метод класса, который преобразует число с плавающей точкой в десятичное число точно.372373Примечание: *Decimal.from\_float(0.1)* не то же самое, что *Decimal('0.1')*. Поскольку 0.1 нельзя точно представить в двоичной арифметике с плавающей точкой, значение хранится как ближайшее представимое значение, равное *0x1.999999999999ap-4*. Эквивалентное десятичное значение – это *0.1000000000000000055511151231257827021181583404541015625*.374375> **Примечание**376>377> Начиная с Python 2.7, экземпляр [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) можно также создать напрямую из [`float`](https://python-all.ru/2.7/library/functions.html#float).378379```pycon380>>> Decimal.from_float(0.1)381Decimal('0.1000000000000000055511151231257827021181583404541015625')382>>> Decimal.from_float(float('nan'))383Decimal('NaN')384>>> Decimal.from_float(float('inf'))385Decimal('Infinity')386>>> Decimal.from_float(float('-inf'))387Decimal('-Infinity')388```389390Новое в версии 2.7.391392#### `fma(other, third[, context])`393394Совмещённое умножение-сложение. Возвращает self\*other+third без округления промежуточного произведения self\*other.395396```python397>>> Decimal(2).fma(3, 5)398Decimal('11')399```400401Новое в версии 2.6.402403#### `is_canonical()`404405Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент канонический, и [`False`](https://python-all.ru/2.7/library/constants.html#False) в противном случае. В настоящее время экземпляр [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) всегда является каноническим, поэтому данная операция всегда возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True).406407Новое в версии 2.6.408409#### `is_finite()`410411Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент – конечное число, и [`False`](https://python-all.ru/2.7/library/constants.html#False), если аргумент – бесконечность или NaN.412413Новое в версии 2.6.414415#### `is_infinite()`416417Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент – положительная или отрицательная бесконечность, и [`False`](https://python-all.ru/2.7/library/constants.html#False) в противном случае.418419Новое в версии 2.6.420421#### `is_nan()`422423Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент – (тихий или сигнальный) NaN, и [`False`](https://python-all.ru/2.7/library/constants.html#False) в противном случае.424425Новое в версии 2.6.426427#### `is_normal()`428429Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент является *нормальным* конечным ненулевым числом со скорректированной экспонентой, большей или равной *Emin*. Возвращает [`False`](https://python-all.ru/2.7/library/constants.html#False), если аргумент – ноль, субнормальное число, бесконечность или NaN. Обратите внимание, что термин *нормальный* используется здесь в ином смысле по сравнению с методом [`normalize()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.normalize), который служит для создания канонических значений.430431Новое в версии 2.6.432433#### `is_qnan()`434435Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент – тихий NaN, и [`False`](https://python-all.ru/2.7/library/constants.html#False) в противном случае.436437Новое в версии 2.6.438439#### `is_signed()`440441Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент имеет отрицательный знак, и [`False`](https://python-all.ru/2.7/library/constants.html#False) в противном случае. Обратите внимание, что нули и NaN могут иметь знак.442443Новое в версии 2.6.444445#### `is_snan()`446447Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент – сигнальный NaN, и [`False`](https://python-all.ru/2.7/library/constants.html#False) в противном случае.448449Новое в версии 2.6.450451#### `is_subnormal()`452453Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент субнормальный, и [`False`](https://python-all.ru/2.7/library/constants.html#False) в противном случае. Число является субнормальным, если оно ненулевое, конечное и имеет скорректированную экспоненту меньше *Emin*.454455Новое в версии 2.6.456457#### `is_zero()`458459Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если аргумент – (положительный или отрицательный) ноль, и [`False`](https://python-all.ru/2.7/library/constants.html#False) в противном случае.460461Новое в версии 2.6.462463#### `ln([context])`464465Возвращает натуральный (по основанию e) логарифм операнда. Результат правильно округляется с использованием режима округления `ROUND_HALF_EVEN`.466467Новое в версии 2.6.468469#### `log10([context])`470471Возвращает десятичный логарифм операнда. Результат правильно округляется с использованием режима округления `ROUND_HALF_EVEN`.472473Новое в версии 2.6.474475#### `logb([context])`476477Для ненулевого числа возвращает скорректированный порядок операнда в виде экземпляра [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal). Если операнд – ноль, то возвращается `Decimal('-Infinity')` и поднимается флаг [`DivisionByZero`](https://python-all.ru/2.7/library/decimal.html#decimal.DivisionByZero). Если операнд – бесконечность, то возвращается `Decimal('Infinity')`.478479Новое в версии 2.6.480481#### `logical_and(other[, context])`482483[`logical_and()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.logical_and) – логическая операция, которая принимает два *логических операнда* (см. [Логические операнды](https://python-all.ru/2.7/library/decimal.html#logical-operands-label)). Результат – поразрядное `and` двух операндов.484485Новое в версии 2.6.486487#### `logical_invert([context])`488489[`logical_invert()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.logical_invert) – логическая операция. Результат – поразрядная инверсия операнда.490491Новое в версии 2.6.492493#### `logical_or(other[, context])`494495[`logical_or()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.logical_or) – логическая операция, которая принимает два *логических операнда* (см. [Логические операнды](https://python-all.ru/2.7/library/decimal.html#logical-operands-label)). Результат – поразрядное `or` двух операндов.496497Новое в версии 2.6.498499#### `logical_xor(other[, context])`500501[`logical_xor()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.logical_xor) – логическая операция, которая принимает два *логических операнда* (см. [Логические операнды](https://python-all.ru/2.7/library/decimal.html#logical-operands-label)). Результат – поразрядное исключающее ИЛИ двух операндов.502503Новое в версии 2.6.504505#### `max(other[, context])`506507Подобно `max(self, other)`, за исключением того, что перед возвратом применяется правило округления контекста и что значения `NaN` либо сигнализируются, либо игнорируются (в зависимости от контекста и того, являются ли они сигнализирующими или тихими).508509#### `max_mag(other[, context])`510511Подобно методу [`max()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.max), но сравнение выполняется с использованием абсолютных значений операндов.512513Новое в версии 2.6.514515#### `min(other[, context])`516517Подобно `min(self, other)`, за исключением того, что перед возвратом применяется правило округления контекста и что значения `NaN` либо сигнализируются, либо игнорируются (в зависимости от контекста и того, являются ли они сигнализирующими или тихими).518519#### `min_mag(other[, context])`520521Подобно методу [`min()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.min), но сравнение выполняется с использованием абсолютных значений операндов.522523Новое в версии 2.6.524525#### `next_minus([context])`526527Возвращает наибольшее число, представимое в заданном контексте (или в контексте текущего потока, если контекст не задан), которое меньше заданного операнда.528529Новое в версии 2.6.530531#### `next_plus([context])`532533Возвращает наименьшее число, представимое в заданном контексте (или в контексте текущего потока, если контекст не задан), которое больше заданного операнда.534535Новое в версии 2.6.536537#### `next_toward(other[, context])`538539Если два операнда не равны, возвращает число, ближайшее к первому операнду в направлении второго операнда. Если оба операнда численно равны, возвращает копию первого операнда со знаком, установленным таким же, как знак второго операнда.540541Новое в версии 2.6.542543#### `normalize([context])`544545Нормализует число, удаляя конечные нули справа и преобразуя любой результат, равный `Decimal('0')`, в `Decimal('0e0')`. Используется для получения канонических значений атрибутов класса эквивалентности. Например, `Decimal('32.100')` и `Decimal('0.321000e+2')` оба нормализуются до эквивалентного значения `Decimal('32.1')`.546547#### `number_class([context])`548549Возвращает строку, описывающую *класс* операнда. Возвращаемое значение является одной из следующих десяти строк.550551- `"-Infinity"` – указывает, что операнд является отрицательной бесконечностью.552- `"-Normal"` – указывает, что операнд является отрицательным нормальным числом.553- `"-Subnormal"` – указывает, что операнд отрицательный и субнормальный.554- `"-Zero"` – указывает, что операнд является отрицательным нулём.555- `"+Zero"` – указывает, что операнд является положительным нулём.556- `"+Subnormal"` – указывает, что операнд положительный и субнормальный.557- `"+Normal"` – указывает, что операнд является положительным нормальным числом.558- `"+Infinity"` – указывает, что операнд является положительной бесконечностью.559- `"NaN"` – указывает, что операнд является тихим NaN (не числом).560- `"sNaN"` – указывает, что операнд является сигнализирующим NaN.561562Новое в версии 2.6.563564#### `quantize(exp[, rounding[, context[, watchexp]]])`565566Возвращает значение, равное первому операнду после округления и имеющее экспоненту второго операнда.567568```python569>>> Decimal('1.41421356').quantize(Decimal('1.000'))570Decimal('1.414')571```572573В отличие от других операций, если длина коэффициента после операции quantize превышает точность, то сигнализируется [`InvalidOperation`](https://python-all.ru/2.7/library/decimal.html#decimal.InvalidOperation). Это гарантирует, что, за исключением ошибочных ситуаций, экспонента после квантования всегда равна экспоненте правого операнда.574575Также, в отличие от других операций, quantize никогда не сигнализирует Underflow, даже если результат субнормален и неточен.576577Если экспонента второго операнда больше, чем первого, может потребоваться округление. В этом случае режим округления определяется аргументом `rounding`, если он передан, иначе аргументом `context`; если ни один из аргументов не передан, используется режим округления контекста текущего потока.578579Если *watchexp* установлен (по умолчанию), то ошибка возвращается, когда результирующая экспонента больше `Emax` или меньше `Etiny`.580581#### `radix()`582583Возвращает `Decimal(10)` – основание системы счисления (базу), в которой класс [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) выполняет все арифметические операции. Включено для совместимости со спецификацией.584585Новое в версии 2.6.586587#### `remainder_near(other[, context])`588589Возвращает остаток от деления *self* на *other*. Отличается от `self % other` тем, что знак остатка выбирается так, чтобы минимизировать его абсолютное значение. Точнее, возвращаемое значение равно `self - n * other`, где `n` – целое число, ближайшее к точному значению `self / other`, а если два целых числа одинаково близки, выбирается чётное.590591Если результат равен нулю, его знак будет знаком *self*.592593```python594>>> Decimal(18).remainder_near(Decimal(10))595Decimal('-2')596>>> Decimal(25).remainder_near(Decimal(10))597Decimal('5')598>>> Decimal(35).remainder_near(Decimal(10))599Decimal('-5')600```601602#### `rotate(other[, context])`603604Возвращает результат вращения цифр первого операнда на величину, заданную вторым операндом. Второй операнд должен быть целым числом в диапазоне от -precision до precision. Абсолютное значение второго операнда задаёт количество позиций для вращения. Если второй операнд положителен, вращение выполняется влево; в противном случае вращение выполняется вправо. Коэффициент первого операнда при необходимости дополняется слева нулями до длины precision. Знак и экспонента первого операнда не изменяются.605606Новое в версии 2.6.607608#### `same_quantum(other[, context])`609610Проверяет, имеют ли self и other одинаковую экспоненту или оба равны `NaN`.611612#### `scaleb(other[, context])`613614Возвращает первый операнд с экспонентой, скорректированной на второй операнд. Эквивалентно умножению первого операнда на `10**other`. Второй операнд должен быть целым числом.615616Новое в версии 2.6.617618#### `shift(other[, context])`619620Возвращает результат сдвига цифр первого операнда на величину, заданную вторым операндом. Второй операнд должен быть целым числом в диапазоне от -precision до precision. Абсолютное значение второго операнда задаёт количество позиций для сдвига. Если второй операнд положителен, сдвиг выполняется влево; в противном случае сдвиг выполняется вправо. Вдвигаемые в коэффициент цифры являются нулями. Знак и экспонента первого операнда не изменяются.621622Новое в версии 2.6.623624#### `sqrt([context])`625626Возвращает квадратный корень аргумента с полной точностью.627628#### `to_eng_string([context])`629630Преобразует в строку, используя инженерную запись, если нужен показатель степени.631632В инженерной записи показатель степени кратен трём. Из-за этого слева от десятичной запятой может оставаться до трёх цифр, и может потребоваться добавление одного или двух конечных нулей.633634Например, это преобразует `Decimal('123E+1')` в `Decimal('1.23E+3')`.635636#### `to_integral([rounding[, context]])`637638Идентичен методу [`to_integral_value()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.to_integral_value). Имя `to_integral` сохранено для совместимости со старыми версиями.639640#### `to_integral_exact([rounding[, context]])`641642Округляет до ближайшего целого, сигнализируя [`Inexact`](https://python-all.ru/2.7/library/decimal.html#decimal.Inexact) или [`Rounded`](https://python-all.ru/2.7/library/decimal.html#decimal.Rounded) в зависимости от ситуации, если округление происходит. Режим округления определяется параметром `rounding`, если он передан, иначе переданным `context`. Если ни один из параметров не передан, используется режим округления текущего контекста.643644Новое в версии 2.6.645646#### `to_integral_value([rounding[, context]])`647648Округляет до ближайшего целого без сигнализации [`Inexact`](https://python-all.ru/2.7/library/decimal.html#decimal.Inexact) или [`Rounded`](https://python-all.ru/2.7/library/decimal.html#decimal.Rounded). Если передан, применяет *rounding*; в противном случае использует метод округления из предоставленного *context* или текущего контекста.649650Изменено в версии 2.6: переименовано из `to_integral` в `to_integral_value`. Старое имя остаётся действительным для совместимости.651652### 9.4.2.1. Логические операнды653654Методы `logical_and()`, `logical_invert()`, `logical_or()` и `logical_xor()` ожидают, что их аргументы будут *логическими операндами*. *Логический операнд* – это экземпляр [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal), у которого экспонента и знак равны нулю, а все цифры равны либо `0`, либо `1`.655656## 9.4.3. Объекты контекста657658Контексты – это среды для арифметических операций. Они управляют точностью, задают правила округления, определяют, какие сигналы обрабатываются как исключения, и ограничивают диапазон для экспонент.659660Каждый поток имеет собственный текущий контекст, доступ к которому или изменение которого осуществляется с помощью функций [`getcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.getcontext) и [`setcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.setcontext):661662#### `decimal.getcontext()`663664Возвращает текущий контекст активного потока.665666#### `decimal.setcontext(c)`667668Устанавливает текущий контекст активного потока в *c*.669670Начиная с Python 2.5, для временного изменения активного контекста можно также использовать инструкцию [`with`](https://python-all.ru/2.7/reference/compound_stmts.html#with) и функцию [`localcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.localcontext).671672#### `decimal.localcontext([c])`673674Возвращает менеджер контекста, который устанавливает текущий контекст для активного потока в копию *c* при входе в оператор with и восстанавливает предыдущий контекст при выходе из оператора with. Если контекст не указан, используется копия текущего контекста.675676Новое в версии 2.5.677678Например, следующий код устанавливает текущую точность десятичных чисел в 42 знака, выполняет вычисление и затем автоматически восстанавливает предыдущий контекст:679680```python681from decimal import localcontext682683with localcontext() as ctx:684    ctx.prec = 42   # Выполнить вычисление с высокой точностью685    s = calculate_something()686s = +s  # Округлить конечный результат до стандартной точности687688with localcontext(BasicContext):      # временно использовать BasicContext689    print Decimal(1) / Decimal(7)690    print Decimal(355) / Decimal(113)691```692693Новые контексты также можно создать с помощью конструктора [`Context`](https://python-all.ru/2.7/library/decimal.html#decimal.Context), описанного ниже. Кроме того, модуль предоставляет три готовых контекста:694695#### `class decimal.BasicContext`696697Это стандартный контекст, определённый спецификацией General Decimal Arithmetic Specification. Точность установлена в девять. Округление установлено в `ROUND_HALF_UP`. Все флаги сброшены. Все ловушки включены (обрабатываются как исключения), кроме [`Inexact`](https://python-all.ru/2.7/library/decimal.html#decimal.Inexact), [`Rounded`](https://python-all.ru/2.7/library/decimal.html#decimal.Rounded) и [`Subnormal`](https://python-all.ru/2.7/library/decimal.html#decimal.Subnormal).698699Поскольку многие ловушки включены, этот контекст полезен для отладки.700701#### `class decimal.ExtendedContext`702703Это стандартный контекст, определённый спецификацией General Decimal Arithmetic Specification. Точность установлена в девять. Округление установлено в `ROUND_HALF_EVEN`. Все флаги сброшены. Никакие ловушки не включены (поэтому исключения не возникают во время вычислений).704705Поскольку ловушки отключены, этот контекст полезен для приложений, которые предпочитают получать в результате значения `NaN` или `Infinity` вместо возбуждения исключений. Это позволяет приложению завершить выполнение при наличии условий, которые в противном случае остановили бы программу.706707#### `class decimal.DefaultContext`708709Этот контекст используется конструктором [`Context`](https://python-all.ru/2.7/library/decimal.html#decimal.Context) в качестве прототипа для новых контекстов. Изменение поля (например, точности) приводит к изменению значения по умолчанию для новых контекстов, создаваемых конструктором [`Context`](https://python-all.ru/2.7/library/decimal.html#decimal.Context).710711Этот контекст наиболее полезен в многопоточных средах. Изменение одного из полей до запуска потоков приводит к установке общесистемных значений по умолчанию. Изменять поля после запуска потоков не рекомендуется, так как это потребовало бы синхронизации потоков для предотвращения состояний гонки.712713В однопоточных средах лучше вообще не использовать этот контекст. Вместо этого просто создавайте контексты явно, как описано ниже.714715Значения по умолчанию: precision=28, rounding=ROUND\_HALF\_EVEN, включены ловушки для Overflow, InvalidOperation и DivisionByZero.716717В дополнение к трём встроенным контекстам новые контексты можно создать с помощью конструктора [`Context`](https://python-all.ru/2.7/library/decimal.html#decimal.Context).718719#### `class decimal.Context(prec=None, rounding=None, traps=None, flags=None, Emin=None, Emax=None, capitals=1)`720721Создаёт новый контекст. Если поле не указано или равно [`None`](https://python-all.ru/2.7/library/constants.html#None), значения по умолчанию копируются из [`DefaultContext`](https://python-all.ru/2.7/library/decimal.html#decimal.DefaultContext). Если поле *flags* не указано или равно [`None`](https://python-all.ru/2.7/library/constants.html#None), все флаги сбрасываются.722723Поле *prec* – это положительное целое число, которое задаёт точность арифметических операций в контексте.724725Параметр *rounding* может принимать одно из следующих значений:726727- `ROUND_CEILING``Infinity`),728- `ROUND_DOWN` (к нулю),729- `ROUND_FLOOR``-Infinity`),730- `ROUND_HALF_DOWN` (к ближайшему, при равенстве – к нулю),731- `ROUND_HALF_EVEN` (к ближайшему, при равенстве – к ближайшему чётному целому),732- `ROUND_HALF_UP` (к ближайшему, при равенстве – от нуля), или733- `ROUND_UP` (от нуля).734- `ROUND_05UP` (от нуля, если последняя цифра после округления к нулю была бы 0 или 5; иначе к нулю)735736Поля *traps* и *flags* содержат список сигналов, которые необходимо установить. Как правило, для новых контекстов следует задавать только ловушки (traps), а флаги (flags) оставлять сброшенными.737738Поля *Emin* и *Emax* – это целые числа, задающие допустимые внешние границы для показателей степени.739740Поле *capitals* может быть равно `0` или `1` (значение по умолчанию). Если установлено `1`, порядок выводится с заглавной `E`; в противном случае используется строчная `e`: `Decimal('6.02e+23')`.741742Изменено в версии 2.6: добавлен режим округления `ROUND_05UP`.743744Класс [`Context`](https://python-all.ru/2.7/library/decimal.html#decimal.Context) определяет несколько методов общего назначения, а также большое количество методов для выполнения арифметических операций непосредственно в заданном контексте. Кроме того, для каждого из методов [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal), описанных выше (за исключением методов `adjusted()` и `as_tuple()`), существует соответствующий метод [`Context`](https://python-all.ru/2.7/library/decimal.html#decimal.Context). Например, для экземпляра [`Context`](https://python-all.ru/2.7/library/decimal.html#decimal.Context) `C` и экземпляра [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) `x` `C.exp(x)` эквивалентно `x.exp(context=C)`. Каждый метод [`Context`](https://python-all.ru/2.7/library/decimal.html#decimal.Context) принимает целое число Python (экземпляр [`int`](https://python-all.ru/2.7/library/functions.html#int) или [`long`](https://python-all.ru/2.7/library/functions.html#long)) везде, где принимается экземпляр Decimal.745746#### `clear_flags()`747748Сбрасывает все флаги в `0`.749750#### `copy()`751752Возвращает копию контекста.753754#### `copy_decimal(num)`755756Возвращает копию экземпляра Decimal num.757758#### `create_decimal(num)`759760Создаёт новый экземпляр Decimal из *num*, но используя *self* в качестве контекста. В отличие от конструктора [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal), к преобразованию применяются точность контекста, метод округления, флаги и ловушки.761762Это полезно, поскольку константы часто задаются с большей точностью, чем требуется приложению. Ещё одно преимущество в том, что округление немедленно устраняет нежелательные эффекты от цифр за пределами текущей точности. В следующем примере использование неокруглённых входных данных означает, что добавление нуля к сумме может изменить результат:763764```pycon765>>> getcontext().prec = 3766>>> Decimal('3.4445') + Decimal('1.0023')767Decimal('4.45')768>>> Decimal('3.4445') + Decimal(0) + Decimal('1.0023')769Decimal('4.44')770```771772Этот метод реализует операцию преобразования в число из спецификации IBM. Если аргумент – строка, начальные и конечные пробелы не допускаются.773774#### `create_decimal_from_float(f)`775776Создаёт новый экземпляр Decimal из числа с плавающей точкой *f*, округляя с использованием *self* в качестве контекста. В отличие от метода класса [`Decimal.from_float()`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal.from_float), к преобразованию применяются точность контекста, метод округления, флаги и ловушки.777778```pycon779>>> context = Context(prec=5, rounding=ROUND_DOWN)780>>> context.create_decimal_from_float(math.pi)781Decimal('3.1415')782>>> context = Context(prec=5, traps=[Inexact])783>>> context.create_decimal_from_float(math.pi)784Traceback (most recent call last):785    ...786Inexact: None787```788789Новое в версии 2.7.790791#### `Etiny()`792793Возвращает значение, равное `Emin - prec + 1`, которое является минимальным значением экспоненты для субнормальных результатов. При антипереполнении (underflow) экспонента устанавливается в [`Etiny`](https://python-all.ru/2.7/library/decimal.html#decimal.Context.Etiny).794795#### `Etop()`796797Возвращает значение, равное `Emax - prec + 1`.798799Обычный подход к работе с десятичными числами заключается в создании экземпляров [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) и последующем применении арифметических операций, которые выполняются в текущем контексте активного потока. Альтернативный подход – использовать методы контекста для вычислений в заданном контексте. Эти методы аналогичны методам класса [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal) и здесь лишь кратко перечислены.800801#### `abs(x)`802803Возвращает абсолютное значение *x*.804805#### `add(x, y)`806807Возвращает сумму *x* и *y*.808809#### `canonical(x)`810811Возвращает тот же объект Decimal *x*.812813#### `compare(x, y)`814815Сравнивает *x* и *y* численно.816817#### `compare_signal(x, y)`818819Сравнивает значения двух операндов численно.820821#### `compare_total(x, y)`822823Сравнивает два операнда по их абстрактному представлению.824825#### `compare_total_mag(x, y)`826827Сравнивает два операнда по их абстрактному представлению, игнорируя знак.828829#### `copy_abs(x)`830831Возвращает копию *x* с установленным в 0 знаком.832833#### `copy_negate(x)`834835Возвращает копию *x* с инвертированным знаком.836837#### `copy_sign(x, y)`838839Копирует знак из *y* в *x*.840841#### `divide(x, y)`842843Возвращает *x*, делённое на *y*.844845#### `divide_int(x, y)`846847Возвращает *x*, делённое на *y*, с усечением до целого.848849#### `divmod(x, y)`850851Делит два числа и возвращает целую часть результата.852853#### `exp(x)`854855Возвращает *e \*\* x*.856857#### `fma(x, y, z)`858859Возвращает *x*, умноженное на *y*, плюс *z*.860861#### `is_canonical(x)`862863Возвращает `True`, если *x* является каноническим; в противном случае возвращает `False`.864865#### `is_finite(x)`866867Возвращает `True`, если *x* является конечным; в противном случае возвращает `False`.868869#### `is_infinite(x)`870871Возвращает `True`, если *x* является бесконечным; в противном случае возвращает `False`.872873#### `is_nan(x)`874875Возвращает `True`, если *x* является qNaN или sNaN; в противном случае возвращает `False`.876877#### `is_normal(x)`878879Возвращает `True`, если *x* является нормальным числом; в противном случае возвращает `False`.880881#### `is_qnan(x)`882883Возвращает `True`, если *x* является тихим NaN; в противном случае возвращает `False`.884885#### `is_signed(x)`886887Возвращает `True`, если *x* является отрицательным; в противном случае возвращает `False`.888889#### `is_snan(x)`890891Возвращает `True`, если *x* является сигнальным NaN; в противном случае возвращает `False`.892893#### `is_subnormal(x)`894895Возвращает `True`, если *x* является субнормальным; в противном случае возвращает `False`.896897#### `is_zero(x)`898899Возвращает `True`, если *x* является нулём; в противном случае возвращает `False`.900901#### `ln(x)`902903Возвращает натуральный (по основанию e) логарифм *x*.904905#### `log10(x)`906907Возвращает десятичный логарифм *x*.908909#### `logb(x)`910911Возвращает показатель степени величины старшего разряда операнда.912913#### `logical_and(x, y)`914915Применяет логическую операцию *and* к соответствующим цифрам операндов.916917#### `logical_invert(x)`918919Инвертирует все цифры в *x*.920921#### `logical_or(x, y)`922923Применяет логическую операцию *or* к соответствующим цифрам операндов.924925#### `logical_xor(x, y)`926927Применяет логическую операцию *xor* к соответствующим цифрам операндов.928929#### `max(x, y)`930931Сравнивает два числа и возвращает наибольшее.932933#### `max_mag(x, y)`934935Сравнивает числа по модулю (игнорируя знак).936937#### `min(x, y)`938939Сравнивает два числа и возвращает наименьшее.940941#### `min_mag(x, y)`942943Сравнивает числа по модулю (игнорируя знак).944945#### `minus(x)`946947Минус соответствует унарному префиксному оператору минус в Python.948949#### `multiply(x, y)`950951Возвращает произведение *x* и *y*.952953#### `next_minus(x)`954955Возвращает наибольшее представимое число, меньшее чем *x*.956957#### `next_plus(x)`958959Возвращает наименьшее представимое число, большее чем *x*.960961#### `next_toward(x, y)`962963Возвращает число, ближайшее к *x* в направлении к *y*.964965#### `normalize(x)`966967Приводит *x* к простейшей форме.968969#### `number_class(x)`970971Возвращает указание на класс *x*.972973#### `plus(x)`974975Plus соответствует унарному префиксному оператору плюс в Python. Эта операция применяет точность и округление контекста, поэтому она *не* является тождественной операцией.976977#### `power(x, y[, modulo])`978979Возвращает `x` в степени `y`, приведённое по модулю `modulo`, если он задан.980981С двумя аргументами вычисляет `x**y`. Если `x` отрицателен, то `y` должен быть целым. Результат будет неточным, если `y` не является целым и результат не конечен и не может быть точно выражен в цифрах 'precision'. Результат всегда должен быть правильно округлён с использованием режима округления контекста текущего потока.982983С тремя аргументами вычисляет `(x**y) % modulo`. Для формы с тремя аргументами действуют следующие ограничения на аргументы:984985> - все три аргумента должны быть целыми986> - `y` должно быть неотрицательным987> - по крайней мере один из `x` или `y` должен быть ненулевым988> - `modulo` должно быть ненулевым и содержать не более ‘precision’ цифр989990Значение, получаемое из `Context.power(x, y, modulo)`, равно значению, которое было бы получено при вычислении `(x**y) % modulo` с неограниченной точностью, но вычисляется более эффективно. Показатель степени результата равен нулю, независимо от показателей степени `x`, `y` и `modulo`. Результат всегда точен.991992Изменено в версии 2.6: `y` теперь может быть нецелым в `x**y`. Более строгие требования для версии с тремя аргументами.993994#### `quantize(x, y)`995996Возвращает значение, равное *x* (с округлением), с экспонентой *y*.997998#### `radix()`9991000Просто возвращает 10, так как это Decimal, :)10011002#### `remainder(x, y)`10031004Возвращает остаток от целочисленного деления.10051006Знак результата, если он не равен нулю, совпадает со знаком исходного делимого.10071008#### `remainder_near(x, y)`10091010Возвращает `x - y * n`, где *n* – целое число, ближайшее к точному значению `x / y` (если результат равен 0, то его знак будет знаком *x*).10111012#### `rotate(x, y)`10131014Возвращает циклически сдвинутую копию *x* на *y* раз.10151016#### `same_quantum(x, y)`10171018Возвращает `True`, если два операнда имеют одинаковую экспоненту.10191020#### `scaleb(x, y)`10211022Возвращает первый операнд после добавления второго значения к его экспоненте.10231024#### `shift(x, y)`10251026Возвращает сдвинутую копию *x* на *y* раз.10271028#### `sqrt(x)`10291030Квадратный корень неотрицательного числа с точностью контекста.10311032#### `subtract(x, y)`10331034Возвращает разность *x* и *y*.10351036#### `to_eng_string(x)`10371038Преобразует в строку, используя инженерную запись, если нужен показатель степени.10391040В инженерной записи показатель степени кратен трём. Из-за этого слева от десятичной запятой может оставаться до трёх цифр, и может потребоваться добавление одного или двух конечных нулей.10411042#### `to_integral_exact(x)`10431044Округляет до целого.10451046#### `to_sci_string(x)`10471048Преобразует число в строку, используя научную запись.10491050## 9.4.4. Сигналы10511052Сигналы представляют условия, возникающие во время вычислений. Каждый соответствует одному флагу контекста и одному включателю ловушки контекста.10531054Флаг контекста устанавливается при возникновении условия. После вычисления флаги могут быть проверены в информационных целях (например, чтобы определить, было ли вычисление точным). После проверки флагов необходимо очистить все флаги перед началом следующего вычисления.10551056Если для сигнала установлен включатель ловушки контекста, то условие вызывает возбуждение исключения Python. Например, если установлена ловушка [`DivisionByZero`](https://python-all.ru/2.7/library/decimal.html#decimal.DivisionByZero), то при возникновении условия возбуждается исключение [`DivisionByZero`](https://python-all.ru/2.7/library/decimal.html#decimal.DivisionByZero).10571058#### `class decimal.Clamped`10591060Изменён показатель степени для соответствия ограничениям представления.10611062Обычно усечение происходит, когда показатель степени выходит за пределы ограничений контекста `Emin` и `Emax`. Если возможно, показатель степени уменьшается для соответствия путём добавления нулей к коэффициенту.10631064#### `class decimal.DecimalException`10651066Базовый класс для других сигналов и подкласс [`ArithmeticError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.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 % x1092x._rescale( non-integer )1093sqrt(-x) and x > 010940 ** 01095x ** (non-integer)1096x ** Infinity1097```10981099#### `class decimal.Overflow`11001101Числовое переполнение.11021103Указывает, что показатель степени больше `Emax` после округления. Если не перехвачена, результат зависит от режима округления: либо округление внутрь до наибольшего представимого конечного числа, либо округление наружу до `Infinity`. В любом случае также сигнализируются [`Inexact`](https://python-all.ru/2.7/library/decimal.html#decimal.Inexact) и [`Rounded`](https://python-all.ru/2.7/library/decimal.html#decimal.Rounded).11041105#### `class decimal.Rounded`11061107Произошло округление, хотя, возможно, информация не была потеряна.11081109Срабатывает при каждом округлении, отбрасывающем цифры, даже если эти цифры нулевые (например, при округлении `5.00` до `5.0`). Если не перехвачено, возвращает результат без изменений. Этот сигнал используется для обнаружения потери значащих цифр.11101111#### `class decimal.Subnormal`11121113Экспонента была меньше `Emin` перед округлением.11141115Возникает, когда результат операции является субнормальным (экспонента слишком мала). Если не перехвачено, возвращает результат без изменений.11161117#### `class decimal.Underflow`11181119Числовое исчерпание с округлением результата до нуля.11201121Возникает, когда субнормальный результат округляется до нуля. Также срабатывают сигналы [`Inexact`](https://python-all.ru/2.7/library/decimal.html#decimal.Inexact) и [`Subnormal`](https://python-all.ru/2.7/library/decimal.html#decimal.Subnormal).11221123В следующей таблице приведена иерархия сигналов:11241125```python1126exceptions.ArithmeticError(exceptions.StandardError)1127    DecimalException1128        Clamped1129        DivisionByZero(DecimalException, exceptions.ZeroDivisionError)1130        Inexact1131            Overflow(Inexact, Rounded)1132            Underflow(Inexact, Rounded, Subnormal)1133        InvalidOperation1134        Rounded1135        Subnormal1136```11371138## 9.4.5. Примечания по числам с плавающей точкой11391140### 9.4.5.1. Уменьшение ошибки округления за счёт повышенной точности11411142Использование десятичной арифметики с плавающей запятой устраняет ошибку десятичного представления (позволяя точно представить `0.1`); однако некоторые операции всё ещё могут приводить к ошибке округления, когда ненулевые цифры превышают фиксированную точность.11431144Влияние ошибки округления может усиливаться при сложении или вычитании почти компенсирующих друг друга величин, что приводит к потере значимости. Кнут приводит два поучительных примера, в которых округлённая арифметика с плавающей точкой с недостаточной точностью приводит к нарушению ассоциативного и дистрибутивного свойств сложения:11451146```pycon1147# Examples from Seminumerical Algorithms, Section 4.2.2.1148>>> from decimal import Decimal, getcontext1149>>> getcontext().prec = 811501151>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')1152>>> (u + v) + w1153Decimal('9.5111111')1154>>> u + (v + w)1155Decimal('10')11561157>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')1158>>> (u*v) + (u*w)1159Decimal('0.01')1160>>> u * (v+w)1161Decimal('0.0060000')1162```11631164Модуль [`decimal`](https://python-all.ru/2.7/library/decimal.html#module-decimal) позволяет восстановить эти свойства за счёт достаточного увеличения точности, чтобы избежать потери значимости:11651166```pycon1167>>> getcontext().prec = 201168>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')1169>>> (u + v) + w1170Decimal('9.51111111')1171>>> u + (v + w)1172Decimal('9.51111111')1173>>>1174>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')1175>>> (u*v) + (u*w)1176Decimal('0.0060000')1177>>> u * (v+w)1178Decimal('0.0060000')1179```11801181### 9.4.5.2. Специальные значения11821183Система чисел модуля [`decimal`](https://python-all.ru/2.7/library/decimal.html#module-decimal) предоставляет особые значения, включая `NaN`, `sNaN`, `-Infinity`, `Infinity`, а также два нуля: `+0` и `-0`.11841185Бесконечности можно создать напрямую с помощью `Decimal('Infinity')`. Также, они могут возникать при делении на ноль, если сигнал [`DivisionByZero`](https://python-all.ru/2.7/library/decimal.html#decimal.DivisionByZero) не перехвачен. Аналогично, если не перехвачен сигнал [`Overflow`](https://python-all.ru/2.7/library/decimal.html#decimal.Overflow), бесконечность может получиться при округлении за пределами наибольшего представимого числа.11861187Бесконечности являются знаковыми (аффинными) и могут использоваться в арифметических операциях, где они трактуются как очень большие неопределённые числа. Например, прибавление константы к бесконечности даёт другой бесконечный результат.11881189Некоторые операции являются неопределёнными и возвращают `NaN`, или, если сигнал [`InvalidOperation`](https://python-all.ru/2.7/library/decimal.html#decimal.InvalidOperation) перехвачен, возбуждают исключение. Например, `0/0` возвращает `NaN`, что означает «не число». Этот вид `NaN` является тихим и, будучи созданным, будет распространяться через другие вычисления, всегда давая в результате `NaN`. Такое поведение может быть полезно для серии вычислений, в которых иногда отсутствуют входные данные – оно позволяет продолжить вычисления, помечая конкретные результаты как недействительные.11901191Существует вариант `sNaN`, который подаёт сигнал, а не остаётся тихим после каждой операции. Это полезное возвращаемое значение, когда недействительный результат должен прервать вычисления для специальной обработки.11921193Поведение операторов сравнения Python может быть несколько неожиданным, когда `NaN` участвует в сравнении. Проверка на равенство, где один из операндов является тихим или сигнальным `NaN`, всегда возвращает [`False`](https://python-all.ru/2.7/library/constants.html#False) (даже при выполнении `Decimal('NaN')==Decimal('NaN')`), а проверка на неравенство всегда возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True). Попытка сравнить два Decimal с помощью любого из операторов `<`, `<=`, `>` или `>=` возбуждает сигнал [`InvalidOperation`](https://python-all.ru/2.7/library/decimal.html#decimal.InvalidOperation), если хотя бы один операнд является `NaN`, и возвращает [`False`](https://python-all.ru/2.7/library/constants.html#False), если этот сигнал не перехвачен. Обратите внимание, что спецификация General Decimal Arithmetic не определяет поведение прямых сравнений; эти правила для сравнений, включающих `NaN`, взяты из стандарта IEEE 854 (см. Таблицу 3 в разделе 5.7). Для обеспечения строгого соответствия стандартам используйте вместо этого методы `compare()` и `compare-signal()`.11941195Знаковые нули могут возникать в результате вычислений, приводящих к исчерпанию. Они сохраняют знак, который получился бы, если бы вычисления выполнялись с большей точностью. Поскольку их величина равна нулю, положительный и отрицательный нули считаются равными, а их знак является информационным.11961197Помимо двух знаковых нулей, которые различны, но равны, существуют различные представления нуля с разной точностью, но эквивалентные по значению. К этому нужно немного привыкнуть. Для глаза, привыкшего к нормализованным представлениям чисел с плавающей точкой, не сразу очевидно, что следующее вычисление возвращает значение, равное нулю:11981199```python1200>>> 1 / Decimal('Infinity')1201Decimal('0E-1000000026')1202```12031204## 9.4.6. Работа с потоками12051206Функция [`getcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.getcontext) обращается к разным объектам [`Context`](https://python-all.ru/2.7/library/decimal.html#decimal.Context) для каждого потока. Наличие отдельных контекстов потоков означает, что потоки могут вносить изменения (например, `getcontext.prec=10`), не мешая друг другу.12071208Аналогично, функция [`setcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.setcontext) автоматически назначает свою цель текущему потоку.12091210Если [`setcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.setcontext) не был вызван до [`getcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.getcontext), то [`getcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.getcontext) автоматически создаст новый контекст для использования в текущем потоке.12111212Новый контекст копируется из прототипа контекста под названием *DefaultContext*. Чтобы управлять значениями по умолчанию так, чтобы каждый поток использовал одни и те же значения во всём приложении, напрямую измените объект *DefaultContext*. Это следует сделать *до* запуска любых потоков, чтобы не возникло состояния гонки между потоками, вызывающими [`getcontext()`](https://python-all.ru/2.7/library/decimal.html#decimal.getcontext). Например:12131214```python1215# Установить глобальные настройки по умолчанию для всех потоков, которые будут запущены1216DefaultContext.prec = 121217DefaultContext.rounding = ROUND_DOWN1218DefaultContext.traps = ExtendedContext.traps.copy()1219DefaultContext.traps[InvalidOperation] = 11220setcontext(DefaultContext)12211222# После этого потоки можно запускать1223t1.start()1224t2.start()1225t3.start()1226 . . .1227```12281229## 9.4.7. Рецепты12301231Вот несколько рецептов, которые служат вспомогательными функциями и демонстрируют способы работы с классом [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal):12321233```python1234def moneyfmt(value, places=2, curr='', sep=',', dp='.',1235             pos='', neg='-', trailneg=''):1236    """Преобразовать Decimal в строку, отформатированную как денежная сумма.12371238    places:  обязательное количество знаков после десятичной точки1239    curr:    необязательный символ валюты перед знаком (может быть пустым)1240    sep:     необязательный разделитель групп (запятая, точка, пробел или пусто)1241    dp:      указатель десятичной точки (запятая или точка)1242             указывать пустым только при places=01243    pos:     необязательный знак для положительных чисел: '+', пробел или пусто1244    neg:     необязательный знак для отрицательных чисел: '-', '(', пробел или пусто1245    trailneg:необязательный завершающий знак минуса: '-', ')', пробел или пусто12461247    >>> d = Decimal('-1234567.8901')1248    >>> moneyfmt(d, curr='$')1249    '-$1,234,567.89'1250    >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')1251    '1.234.568-'1252    >>> moneyfmt(d, curr='$', neg='(', trailneg=')')1253    '($1,234,567.89)'1254    >>> moneyfmt(Decimal(123456789), sep=' ')1255    '123 456 789.00'1256    >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')1257    '<0.02>'12581259    """1260    q = Decimal(10) ** -places      # 2 знака после запятой --> '0.01'1261    sign, digits, exp = value.quantize(q).as_tuple()1262    result = []1263    digits = map(str, digits)1264    build, next = result.append, digits.pop1265    if sign:1266        build(trailneg)1267    for i in range(places):1268        build(next() if digits else '0')1269    build(dp)1270    if not digits:1271        build('0')1272    i = 01273    while digits:1274        build(next())1275        i += 11276        if i == 3 and digits:1277            i = 01278            build(sep)1279    build(curr)1280    build(neg if sign else pos)1281    return ''.join(reversed(result))12821283def pi():1284    """Вычислить число Пи с текущей точностью.12851286    >>> print pi()1287    3.14159265358979323846264338312881289    """1290    getcontext().prec += 2  # дополнительные цифры для промежуточных шагов1291    three = Decimal(3)      # подставить "three=3.0" вместо обычных чисел с плавающей точкой1292    lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 241293    while s != lasts:1294        lasts = s1295        n, na = n+na, na+81296        d, da = d+da, da+321297        t = (t * n) / d1298        s += t1299    getcontext().prec -= 21300    return +s               # унарный плюс применяет новую точность13011302def exp(x):1303    """Возвращает e, возведённое в степень x. Тип результата соответствует типу входного значения.13041305    >>> print exp(Decimal(1))1306    2.7182818284590452353602874711307    >>> print exp(Decimal(2))1308    7.3890560989306502272304274611309    >>> print exp(2.0)1310    7.389056098931311    >>> print exp(2+0j)1312    (7.38905609893+0j)13131314    """1315    getcontext().prec += 21316    i, lasts, s, fact, num = 0, 0, 1, 1, 11317    while s != lasts:1318        lasts = s1319        i += 11320        fact *= i1321        num *= x1322        s += num / fact1323    getcontext().prec -= 21324    return +s13251326def cos(x):1327    """Возвращает косинус x, измеренного в радианах.13281329    >>> print cos(Decimal('0.5'))1330    0.87758256189037271611628158261331    >>> print cos(0.5)1332    0.877582561891333    >>> print cos(0.5+0j)1334    (0.87758256189+0j)13351336    """1337    getcontext().prec += 21338    i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 11339    while s != lasts:1340        lasts = s1341        i += 21342        fact *= i * (i-1)1343        num *= x * x1344        sign *= -11345        s += num / fact * sign1346    getcontext().prec -= 21347    return +s13481349def sin(x):1350    """Возвращает синус угла x, заданного в радианах.13511352    >>> print sin(Decimal('0.5'))1353    0.47942553860420300027328793521354    >>> print sin(0.5)1355    0.4794255386041356    >>> print sin(0.5+0j)1357    (0.479425538604+0j)13581359    """1360    getcontext().prec += 21361    i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 11362    while s != lasts:1363        lasts = s1364        i += 21365        fact *= i * (i-1)1366        num *= x * x1367        sign *= -11368        s += num / fact * sign1369    getcontext().prec -= 21370    return +s1371```13721373## 9.4.8. Часто задаваемые вопросы по Decimal13741375Вопрос. Вводить `decimal.Decimal('1234.5')` неудобно. Есть ли способ сократить набор при работе в интерактивном интерпретаторе?13761377Ответ. Некоторые пользователи сокращают конструктор до одной буквы:13781379```python1380>>> D = decimal.Decimal1381>>> D('1.23') + D('3.45')1382Decimal('4.68')1383```13841385Вопрос. В приложении с фиксированной запятой с двумя десятичными знаками некоторые входные данные имеют много знаков и нуждаются в округлении. Другие не должны содержать лишних цифр и требуют проверки. Какие методы следует использовать?13861387Ответ. Метод `quantize()` округляет до заданного числа десятичных знаков. Если установлен перехват [`Inexact`](https://python-all.ru/2.7/library/decimal.html#decimal.Inexact), он также полезен для проверки:13881389```python1390>>> TWOPLACES = Decimal(10) ** -2       # то же, что Decimal('0.01')1391```13921393```python1394>>> # Округлить до двух знаков1395>>> Decimal('3.214').quantize(TWOPLACES)1396Decimal('3.21')1397```13981399```python1400>>> # Проверка, что число не выходит за пределы двух знаков1401>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))1402Decimal('3.21')1403```14041405```python1406>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))1407Traceback (most recent call last):1408   ...1409Inexact: None1410```14111412Вопрос. Получив корректные входные данные с двумя знаками, как поддерживать этот инвариант во всём приложении?14131414Ответ. Некоторые операции, такие как сложение, вычитание и умножение на целое число, автоматически сохраняют фиксированную точку. Другие операции, например деление и умножение на нецелое число, изменяют количество десятичных знаков, и после них требуется шаг `quantize()`:14151416```python1417>>> a = Decimal('102.72')           # Начальные значения чисел с фиксированной точкой1418>>> b = Decimal('3.17')1419>>> a + b                           # Сложение сохраняет фиксированную точку1420Decimal('105.89')1421>>> a - b1422Decimal('99.55')1423>>> a * 42                          # Умножение на целое число – тоже1424Decimal('4314.24')1425>>> (a * b).quantize(TWOPLACES)     # Результат умножения на нецелое число нужно квантовать1426Decimal('325.62')1427>>> (b / a).quantize(TWOPLACES)     # И квантовать результат деления1428Decimal('0.03')1429```14301431При разработке приложений с фиксированной запятой удобно определить функции для обработки шага `quantize()`:14321433```python1434>>> def mul(x, y, fp=TWOPLACES):1435...     return (x * y).quantize(fp)1436>>> def div(x, y, fp=TWOPLACES):1437...     return (x / y).quantize(fp)1438```14391440```python1441>>> mul(a, b)                       # Автоматически сохранять фиксированную точку1442Decimal('325.62')1443>>> div(b, a)1444Decimal('0.03')1445```14461447Вопрос. Существует много способов выразить одно и то же значение. Числа `200`, `200.000`, `2E2` и `02E+4` при различной точности имеют одно и то же значение. Есть ли способ преобразовать их в единое узнаваемое каноническое значение?14481449Ответ. Метод `normalize()` отображает все эквивалентные значения в единого представителя:14501451```python1452>>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())1453>>> [v.normalize() for v in values]1454[Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]1455```14561457Вопрос. Некоторые значения decimal всегда выводятся в экспоненциальной записи. Есть ли способ получить неэкспоненциальное представление?14581459Ответ. Для некоторых значений экспоненциальная запись – единственный способ выразить количество значащих цифр в коэффициенте. Например, представление `5.0E+3` в виде `5000` сохраняет значение, но не может показать двухзначную точность оригинала.14601461Если приложению не важно отслеживание значимости, легко можно удалить экспоненту и завершающие нули, потеряв значимость, но сохранив значение без изменений:14621463```python1464def remove_exponent(d):1465    '''Удалить экспоненту и конечные нули.14661467    >>> remove_exponent(Decimal('5E+3'))1468    Decimal('5000')14691470    '''1471    return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()1472```14731474Вопрос. Есть ли способ преобразовать обычный float в [`Decimal`](https://python-all.ru/2.7/library/decimal.html#decimal.Decimal)?14751476A. Да, любое двоичное число с плавающей точкой может быть точно выражено как Decimal, хотя для точного преобразования может потребоваться больше точности, чем подсказывает интуиция:14771478```pycon1479>>> Decimal(math.pi)1480Decimal('3.141592653589793115997963468544185161590576171875')1481```14821483Вопрос. В сложном вычислении как я могу убедиться, что не получил ложный результат из-за недостаточной точности или аномалий округления?14841485Ответ. Модуль decimal упрощает проверку результатов. Рекомендуется перезапускать вычисления с большей точностью и различными режимами округления. Сильно различающиеся результаты указывают на недостаточную точность, проблемы с режимом округления, плохо обусловленные входные данные или численно неустойчивый алгоритм.14861487Вопрос. Я заметил, что точность контекста применяется к результатам операций, но не к входным данным. Есть ли что-то, на что следует обращать внимание при смешивании значений разной точности?14881489Ответ. Да. Принцип заключается в том, что все значения считаются точными, как и арифметические операции с ними. Округляются только результаты. Преимущество для входных данных в том, что «что ввёл, то и получил». Недостаток в том, что результаты могут выглядеть странно, если забыть, что входные данные не округлены:14901491```pycon1492>>> getcontext().prec = 31493>>> Decimal('3.104') + Decimal('2.104')1494Decimal('5.21')1495>>> Decimal('3.104') + Decimal('0.000') + Decimal('2.104')1496Decimal('5.20')1497```14981499Решение – либо увеличить точность, либо принудительно округлить входные данные с помощью унарного плюса:15001501```pycon1502>>> getcontext().prec = 31503>>> +Decimal('1.23456789')      # Унарный плюс вызывает округление1504Decimal('1.23')1505```15061507В качестве альтернативы входные данные можно округлить при создании с помощью метода [`Context.create_decimal()`](https://python-all.ru/2.7/library/decimal.html#decimal.Context.create_decimal):15081509```python1510>>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')1511Decimal('1.2345')1512```1513