Decimal python что это
Перейти к содержимому

Decimal python что это

  • автор:

Модуль decimal в Python, десятичная арифметика

Модуль decimal обеспечивает поддержку быстрой правильно округленной десятичной арифметики с плавающей запятой. Он предлагает несколько преимуществ по сравнению с типом данных float :

  • Десятичное число основано на модели с плавающей точкой, которая была разработана с учетом потребностей людей и обязательно имеет первостепенный руководящий принцип — компьютеры должны обеспечивать арифметику, которая работает так же, как арифметика, которую люди изучают в школе.
  • Десятичные числа могут быть представлены точно. Напротив, числа типа float 1.1 и 2.2 не имеют точных представлений в двоичной формате. Конечные пользователи обычно не ожидают, что 1.1 + 2.2 будет отображаться как 3.3000000000000003.
  • Точность переносится в арифметику. В десятичном формате с плавающей запятой 0,1 + 0,1 + 0,1 — 0,3 точно равно нулю. В двоичной формате результат равен 5.5511151231257827e-017. Хотя значения близки к нулю, различия мешают надежному тестированию на равенство и различия могут накапливаться. По этой причине десятичная дробь предпочтительнее в бухгалтерских приложениях, которые имеют строгие инварианты равенства.
  • Десятичный модуль включает в себя понятие значимых мест, так что 1,30 + 1,20 составляет 2,50. Конечный ноль сохраняется для обозначения значимости. Это обычное представление для денежных приложений. Например 1,3 * 1,2 дает 1,56, а 1,30 * 1,20 дает 1,5600.
  • В отличие от аппаратной двоичной плавающей запятой, модуль decimal имеет изменяемую пользователем точность, по умолчанию до 28 разрядов, которая может быть настолько большой, насколько это необходимо для вычислений:

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

Дизайн модуля основан на трех понятиях: десятичное число, контекст для арифметики и сигналы.

Десятичное число является неизменным. У него есть знак, цифры коэффициента и показатель степени. Для сохранения значимости цифры коэффициента не усекают конечные нули. Десятичные числа также включают специальные значения, такие как Infinity , -Infinity и NaN . Стандарт также отличает -0 от +0.

Контекст для арифметики — это среда, определяющая точность, правила округления, ограничения на экспоненты, флаги, указывающие результаты операций, и средства активации, которые определяют, будут ли сигналы рассматриваться как исключения.

Сигналы — это группы исключительных условий, возникающих в процессе вычислений. В зависимости от потребностей приложения сигналы могут игнорироваться, рассматриваться как информационные или рассматриваться как исключения. Смотрите раздел «Сигналы в модуле decimal «.

Для каждого сигнала есть флаг и активатор ловушек. Когда сигнал встречается, его флаг устанавливается в единицу, затем, если активатор прерывания установлен в единицу, возникает исключение. Флаги являются липкими, поэтому пользователь должен сбросить их перед мониторингом расчетов.

  • КРАТКИЙ ОБЗОР МАТЕРИАЛА.
  • Краткое руководство по модулю decimal
  • Ошибки округления с повышенной точностью
  • Способы работы с классом Decimal
  • Класс Decimal() модуля decimal
  • Методы объекта Decimal()
  • Контексты модуля decimal
  • Класс Context() модуля decimal
  • Режимы округления модуля decimal
  • Сигнальные флаги модуля decimal

Decimal python что это

При работе с числами с плавающей точкой (то есть float) мы сталкиваемся с тем, что в результате вычислений мы получаем не совсем верный результат:

number = 0.1 + 0.1 + 0.1 print(number) # 0.30000000000000004

Проблему может решить использование функции round() , которая округлит число. Однако есть и другой способ, который заключается в использовании встроенного модуля decimal .

Ключевым компонентом для работы с числами в этом модуле является класс Decimal . Для его применения нам надо создать его объект с помощью конструктора. В конструктор передается строковое значение, которое представляет число:

from decimal import Decimal number = Decimal("0.1")

После этого объект Decimal можно использовать в арифметических операциях:

from decimal import Decimal number = Decimal("0.1") number = number + number + number print(number) # 0.3

В операциях с Decimal можно использовать целые числа:

number = Decimal("0.1") number = number + 2

Однако нельзя смешивать в операциях дробные числа float и Decimal:

number = Decimal("0.1") number = number + 0.1 # здесь возникнет ошибка

С помощью дополнительных знаков мы можем определить, сколько будет символов в дробной части числа:

number = Decimal("0.10") number = 3 * number print(number) # 0.30

Строка «0.10» определяет два знака в дробной части, даже если последние символы будут представлять ноль. Соответственно «0.100» представляет три знака в дробной части.

Округление чисел

Объекты Decimal имеют метод quantize() , который позволяет округлять числа. В этот метод в качестве первого аргумента передается также объект Decimal, который указывает формат округления числа:

from decimal import Decimal number = Decimal("0.444") number = number.quantize(Decimal("1.00")) print(number) # 0.44 number = Decimal("0.555678") print(number.quantize(Decimal("1.00"))) # 0.56 number = Decimal("0.999") print(number.quantize(Decimal("1.00"))) # 1.00

Используемая строка «1.00» указывает, что округление будет идти до двух знаков в дробной части.

По умолчанию округление описывается константой ROUND_HALF_EVEN , при котором округление происходит до ближайшего четного числа, если округляемая часть равна 5. Например:

from decimal import Decimal, ROUND_HALF_EVEN number = Decimal("10.025") # 2 - ближайшее четное число print(number.quantize(Decimal("1.00"), ROUND_HALF_EVEN)) # 10.02 number = Decimal("10.035") # 4 - ближайшее четное число print(number.quantize(Decimal("1.00"), ROUND_HALF_EVEN)) # 10.04

Стратегия округления передается в качестве второго параметра в quantize.

Строка «1.00» означает, что округление будет идти до двух чисел в дробной части. Но в первом случае «10.025» — вторым знаком идет 2 — четное число, поэтому, несмотря на то, что следующее число 5, двойка не округляется до тройки.

Во втором случае «10.035» — вторым знаком идет 3 — нечетное число, ближайшим четным числом будет 4, поэтому 35 округляется до 40.

Данное поведение при округлении, возможно, не всем покажется желательным, и в этом случае его можно переопределить, использовав одну из следующих констант:

  • ROUND_HALF_UP : округляет число в сторону повышения, если после него идет число 5 или выше
  • ROUND_HALF_DOWN : округляет число в сторону повышения, если после него идет число больше 5

number = Decimal("10.026") print(number.quantize(Decimal("1.00"), ROUND_HALF_DOWN)) # 10.03 number = Decimal("10.025") print(number.quantize(Decimal("1.00"), ROUND_HALF_DOWN)) # 10.02
number = Decimal("10.005") print(number.quantize(Decimal("1.00"), ROUND_05UP)) # 10.01 number = Decimal("10.025") print(number.quantize(Decimal("1.00"), ROUND_05UP)) # 10.02
number = Decimal("10.021") print(number.quantize(Decimal("1.00"), ROUND_CEILING)) # 10.03 number = Decimal("10.025") print(number.quantize(Decimal("1.00"), ROUND_CEILING)) # 10.03
number = Decimal("10.021") print(number.quantize(Decimal("1.00"), ROUND_FLOOR)) # 10.02 number = Decimal("10.025") print(number.quantize(Decimal("1.00"), ROUND_FLOOR)) # 10.02

decimal — Десятичная арифметика с фиксированной и плавающей точкой¶

Модуль decimal обеспечивает поддержку быстрой арифметики с правильно округленным десятичным числом с плавающей запятой. Он предлагает несколько преимуществ по сравнению с типом данных float :

  • Модуль decimal «основан на модели с плавающей запятой, которая была разработана с учётом потребностей людей с обязательным первостепенным руководящим принципом — компьютеры должны реализовывать арифметику, работающую так же, как изучаемую людьми школьную арифметику», — выдержка из спецификации десятичной арифметики.
  • Десятичные числа могут быть представлены точно. Напротив, у таких чисел, как 1.1 и 2.2 нет точного представления в двоичной системе с плавающей запятой. Конечные пользователи обычно не ожидают, что 1.1 + 2.2 будет отображаться как 3.3000000000000003 , как это происходит с двоичной плавающей запятой.
  • Точность переносится в арифметику. В десятичной системе с плавающей запятой 0.1 + 0.1 + 0.1 — 0.3 в точности равно нулю. В двоичной системе с плавающей запятой результат будет 5.5511151231257827e-017 . Хотя различия близки к нулю, они мешают надежной проверке равенства, и различия могут накапливаться. По этой причине десятичное число предпочтительнее в бухгалтерских приложениях, у которых строгие инварианты равенства.
  • Модуль decimal включает понятие значащих разрядов, так что 1.30 + 1.20 равно 2.50 . Завершающий ноль сохраняется для обозначения значимости. Это обычное представление для денежных приложений. Для умножения в «школьном» подходе используются все числа в множимых. Например, 1.3 * 1.2 дает 1.56 , а 1.30 * 1.20 дает 1.5600 .

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

В основе конструкции модуля лежат три концепции: десятичное число, контекст для арифметики и сигналы.

Десятичное число неизменяемо. У него есть знак, цифры коэффициента и показатель степени. Для сохранения значимости цифры коэффициента не усекают конечные нули. Десятичные дроби также включают специальные значения, такие как Infinity , -Infinity и NaN . Стандарт также отличает -0 от +0 .

Контекст для арифметики — это среда, определяющая точность, правила округления, ограничения экспонент, флаги, указывающие результаты операций, и средства включения ловушек, которые определяют, обрабатываются ли сигналы как исключения. Варианты округления включают ROUND_CEILING , ROUND_DOWN , ROUND_FLOOR , ROUND_HALF_DOWN , ROUND_HALF_EVEN , ROUND_HALF_UP , ROUND_UP и ROUND_05UP .

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

Для каждого сигнала есть флаг и активатор прерывания. Когда сигнал обнаружен, его флаг устанавливается в единицу, затем, если активатор прерывания установлен в единицу, возникает исключение. Флаги залипают, поэтому пользователю необходимо сбросить их перед отслеживанием вычислений.

  • Спецификация общей десятичной арифметики IBM, Общая спецификация десятичной арифметики.

Краткое руководство¶

Обычное начало использования десятичных знаков — это импорт модуля, просмотр текущего контекста с помощью getcontext() и, при необходимости, установка новых значений для точности, округления или включенных прерываний:

>>> from decimal import * >>> getcontext() Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero, InvalidOperation]) >>> getcontext().prec = 7 # Установить новую точность 

Десятичные экземпляры могут быть построены из целых чисел, строк, чисел с плавающей запятой или кортежей. Конструкция из целого числа или числа с плавающей запятой выполняет точное преобразование значения этого целого числа или числа с плавающей запятой. Десятичные числа включают специальные значения, такие как NaN , что означает «Не число», положительные и отрицательные Infinity и -0 :

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

Если перехватывается сигнал FloatOperation , случайное смешивание десятичных знаков и чисел с плавающей запятой в конструкторах или упорядоченных сравнениях вызывает исключение:

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

Добавлено в версии 3.3.

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

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

Если внутренние ограничения версии C превышены, построение десятичной дроби вызывает InvalidOperation :

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

Изменено в версии 3.3.

Десятичные дроби хорошо взаимодействуют с большей частью остального Python. Вот небольшой десятичный летающий цирк с плавающей запятой:

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

И некоторые математические функции также доступны для Decimal:

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

Метод quantize() округляет число до фиксированной степени. Этот метод полезен для денежных приложений, которые часто округляют результаты до фиксированного числа разрядов:

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

Как показано выше, функция getcontext() обращается к текущему контексту и позволяет изменять настройки. Такой подход отвечает потребностям большинства приложений.

Для более сложной работы может быть полезно создать альтернативные контексты с помощью конструктора Context(). Чтобы активировать альтернативу, используйте функцию setcontext() .

В соответствии со стандартом, модуль decimal предоставляет два готовых к использованию стандартных контекста: BasicContext и ExtendedContext . Первый особенно полезен для отладки, потому что многие ловушки включены:

>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN) >>> setcontext(myothercontext) >>> Decimal(1) / Decimal(7) Decimal('0.142857142857142857142857142857142857142857142857142857142857') >>> ExtendedContext Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[]) >>> setcontext(ExtendedContext) >>> Decimal(1) / Decimal(7) Decimal('0.142857143') >>> Decimal(42) / Decimal(0) Decimal('Infinity') >>> setcontext(BasicContext) >>> Decimal(42) / Decimal(0) Traceback (most recent call last): File "", line 1, in -toplevel- Decimal(42) / Decimal(0) DivisionByZero: x / 0 

У контекстов также есть сигнальные флаги для отслеживания исключительных условий, возникающих во время вычислений. Флаги остаются установленными до тех пор, пока они не будут сняты явным образом, поэтому лучше всего сбрасывать флаги перед каждым набором отслеживаемых вычислений с помощью метода clear_flags() .

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

Запись flags показывает, что рациональное приближение к Pi было округлено (цифры, превышающие точность контекста, были отброшены) и что результат неточный (некоторые из отброшенных цифр были ненулевыми).

Индивидуальные ловушки устанавливаются с использованием словаря в поле контекста traps :

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

Большинство программ корректируют текущий контекст только один раз, в начале программы. И во многих приложениях данные преобразуются в Decimal с помощью одного преобразования внутри цикла. С набором контекста и созданными десятичными знаками основная часть программы манипулирует данными не иначе, как с другими числовыми типами Python.

Десятичные объекты¶

class decimal. Decimal ( value=»0″, context=None ) ¶

Создать новый объект Decimal на основе value.

value может быть целым числом, строкой, кортежем, float или другим объектом Decimal . Если value не указан, возвращает Decimal(‘0’) . Если value является строкой, она должна соответствовать синтаксису десятичной числовой строки после удаления начальных и конечных пробельных символов, а также подчеркивания повсюду:

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

Другие Юникод десятичные цифры также разрешены там, где выше digit . К ним относятся десятичные цифры из различных других алфавитов (например, арабско-индийские и деванагарийские цифры), а также цифры полной ширины от ‘\uff10’ до ‘\uff19’ .

Если value — это tuple , у него должно быть три компонента: знак ( 0 для положительного или 1 для отрицательного), tuple цифр и целочисленный показатель степени. Например, Decimal((0, (1, 4, 1, 4), -3)) возвращает Decimal(‘1.414’) .

Если value — это float , двоичное значение с плавающей запятой без потерь преобразуется в его точный десятичный эквивалент. Это преобразование часто может потребовать 53 или более знаков точности. Например, Decimal(float(‘1.1’)) преобразуется в Decimal(‘1.100000000000000088817841970012523233890533447265625’) .

Точность context не влияет на количество хранимых цифр. Это определяется исключительно количеством цифр в value. Например, Decimal(‘3.00000’) записывает все пять нулей, даже если точность контекста равна только трём.

Цель аргумента context — определить, что делать, если value является неверно сформированной строкой. Если контекст перехватывает InvalidOperation , возникает исключение; в противном случае конструктор возвращает новый Decimal со значением NaN .

После создания объекты Decimal неизменны.

Изменено в версии 3.2: Аргументом конструктора теперь может быть экземпляр float .

Изменено в версии 3.3: Аргументы float вызывают исключение, если установлено прерывание FloatOperation . По умолчанию ловушка отключена.

Изменено в версии 3.6: Подчеркивания разрешены для группировки, как и для целочисленных литералов и литералов с плавающей запятой в коде.

У Decimal объектов с плавающей запятой есть много общих свойств с другими встроенными числовыми типами, такими как float и int . Применяются все обычные математические операции и специальные методы. Точно так же десятичные объекты можно копировать, обрабатывать, печатать, использовать в качестве ключей словаря, использовать как элементы множества, сравнивать, сортировать и приводить к другому типу (например, float или int ).

Есть небольшие различия между арифметикой над объектами Decimal и арифметикой с целыми числами и числами с плавающей запятой. Когда оператор остатка % применяется к Decimal объектам, знаком результата является знак числителя, а не знак делителя:

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

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

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

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

Decimal объекты обычно не могут быть объединены с числами с плавающей запятой или экземплярами fractions.Fraction в арифметических операциях: например, попытка добавить Decimal к float вызовет TypeError . Однако можно использовать операторы сравнения Python для сравнения экземпляра Decimal x с другим номером y . Это позволяет избежать запутанных результатов при сравнении чисел разных типов на равенство.

Изменено в версии 3.2: Теперь полностью поддерживаются сравнения смешанного типа между экземплярами Decimal и другими числовыми типами.

В дополнение к стандартным числовым свойствам десятичных объектов с плавающей запятой также есть ряд специализированных методов:

Возвращает скорректированный показатель степени после сдвига крайних правых цифр коэффициента до тех пор, пока не останется только первая цифра: Decimal(‘321e+5’).adjusted() возвращает семь. Используется для определения позиции старшего разряда по отношению к десятичной запятой.

Возвращает пару целых чисел (n, d) , которая представляет данный экземпляр Decimal в виде дроби, в наименьшем значении и с положительным знаменателем:

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

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

Добавлено в версии 3.6.

Возвращает именованный кортеж представление числа: DecimalTuple(sign, digits, exponent) .

Возвращает каноническую кодировку аргумента. В настоящее время кодировка экземпляра Decimal всегда каноническая, поэтому операция возвращает свой аргумент без изменений.

Сравнивает значения двух экземпляров Decimal. compare() возвращает экземпляр Decimal, и если один из операндов — NaN, то результатом будет NaN:

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

compare_signal ( other, context=None ) ¶

Операция идентична методу compare() , за исключением того, что все сигналы NaN. То есть, если ни один из операндов не является сигнальным NaN, то любой тихий операнд NaN обрабатывается так, как если бы он был сигнальным NaN.

compare_total ( other, context=None ) ¶

Сравнивает два операнда, используя их абстрактное представление, а не их числовое значение. Аналогичен методу compare() , но результат даёт полное упорядочение экземпляров Decimal . Два экземпляра Decimal с одинаковым числовым значением, но разными представлениями сравниваются неравными в этом порядке:

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

Тихие и сигнальные NaN также включены в общий порядок. Результатом этой функции будет Decimal(‘0’) , если у обоих операнда одинаковое представление, Decimal(‘-1’) , если первый операнд в общем порядке ниже, чем второй, и Decimal(‘1’) , если первый операнд в общем порядке выше, чем второй операнд. Подробную информацию об общем порядке см. в спецификации.

Операция не зависит от контекста и выполняется тихо: флаги не меняются и округление не выполняется. В качестве исключения версия C может вызвать InvalidOperation, если второй операнд не может быть точно преобразован.

compare_total_mag ( other, context=None ) ¶

Сравнить два операнда, используя их абстрактное представление, а не их значения, как в compare_total() , но игнорируя знак каждого операнда. x.compare_total_mag(y) эквивалентен x.copy_abs().compare_total(y.copy_abs()) .

Операция не зависит от контекста и выполняется тихо: флаги не меняются и округление не выполняется. В качестве исключения версия C может вызвать InvalidOperation, если второй операнд не может быть точно преобразован.

Просто возвращает self, этот метод предназначен только для соответствия спецификации Decimal.

Возвращает абсолютное значение аргумента. Операция не зависит от контекста и выполняется тихо: флаги не меняются и округление не выполняется.

Возвращает отрицание аргумента. Операция не зависит от контекста и выполняется тихо: флаги не меняются и округление не выполняется.

copy_sign ( other, context=None ) ¶

Возвращает копию первого операнда со знаком, установленным таким же, как знак второго операнда. Например:

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

Операция не зависит от контекста и выполняется тихо: флаги не меняются и округление не выполняется. В качестве исключения версия C может вызвать InvalidOperation, если второй операнд не может быть точно преобразован.

Возвращает значение (натуральной) экспоненциальной функции e**x с заданным числом. Результат правильно округлен с использованием режима округления ROUND_HALF_EVEN .

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

from_float ( f ) ¶

Метод класса, который точно преобразует число с плавающей запятой в десятичное число.

Обратите внимание: Decimal.from_float (0.1) не то же самое, что Decimal («0.1») . Поскольку 0.1 не может быть точно представлено в двоичной системе с плавающей запятой, значение сохраняется как ближайшее представимое значение, которое равно «0x1.999999999999ap-4». Это эквивалентно десятичному значению — 0.1000000000000000055511151231257827021181583404541015625.

Начиная с Python 3.2, экземпляр Decimal также может быть сконструирован непосредственно из float .

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

Добавлено в версии 3.1.

fma ( other, third, context=None ) ¶

Слитное умножение-сложение. Возвращает self*other+third без округления промежуточного умножения self*other.

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

is_canonical ( ) ¶

Возвращает True , если аргумент канонический, и False в противном случае. В настоящее время экземпляр Decimal всегда является каноническим, поэтому операция всегда возвращает True .

Возвращает True , если аргумент — конечное число, и False , если аргумент — бесконечность или NaN.

Возвращает True , если аргумент равен положительной или отрицательной бесконечности, и False в противном случае.

Возвращает True , если аргумент (тихий или сигнальный) NaN, и False в противном случае.

Возвращает True , если аргумент является конечным числом normal. Возвращает False , если аргумент равен нулю, субнормальному, бесконечному или NaN.

Возвращает True , если аргумент является тихим NaN, и False в противном случае.

Возвращает True , если у аргумента отрицательный знак, и False в противном случае. Обратите внимание, что и нули, и NaN могут содержать знаки.

Возвращает True , если аргумент является сигнальным NaN, и False в противном случае.

Возвращает True , если аргумент субнормален, и False в противном случае.

Возвращает True , если аргумент является (положительным или отрицательным) нулем, и False в противном случае.

Возвращает натуральный логарифм операнда (с основанием e). Результат правильно округлён с использованием режима округления ROUND_HALF_EVEN .

Возвращает десятичный логарифм операнда. Результат правильно округлен с использованием режима округления ROUND_HALF_EVEN .

Для ненулевого числа возвращает скорректированную экспоненту его операнда как экземпляр Decimal . Если операнд равен нулю, то возвращается Decimal(‘-Infinity’) и поднимается флаг DivisionByZero . Если операнд бесконечен, возвращается Decimal(‘Infinity’) .

logical_and ( other, context=None ) ¶

logical_and() — это логическая операция, которая принимает два логических операнда (см. Логические операнды ). Результатом будет and двух операндов в цифровом виде.

logical_invert() — это логическая операция. Результатом является инверсия операнда по цифрам.

logical_or ( other, context=None ) ¶

logical_or() — это логическая операция, которая принимает два логических операнда (см. Логические операнды ). Результатом будет or двух операндов в цифровом виде.

logical_xor ( other, context=None ) ¶

logical_xor() — это логическая операция, которая принимает два логических операнда (см. Логические операнды ). Результатом является исключающее ИЛИ двух операндов.

Подобен max(self, other) , за исключением того, что перед возвратом применяется правило округления контекста, а значения NaN либо сигнализируются, либо игнорируются (в зависимости от контекста и от того, являются ли они сигнальными или тихими).

Аналогичен методу max() , но сравнение выполняется с использованием абсолютных значений операндов.

Подобен min(self, other) , за исключением того, что правило округления контекста применяется перед возвратом и что значения NaN либо сигнализируются, либо игнорируются (в зависимости от контекста и от того, являются ли они сигнальными или тихими).

Аналогичен методу min() , но сравнение выполняется с использованием абсолютных значений операндов.

Возвращает наибольшее число, представимое в данном контексте (или в контексте текущего потока, если контекст не задан), которое меньше заданного операнда.

Возвращает наименьшее число, представимое в данном контексте (или в контексте текущего потока, если контекст не задан), которое больше, чем данный операнд.

next_toward ( other, context=None ) ¶

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

Нормализует число, удалив крайние правые нули в конце и преобразовав любой результат, равный Decimal(‘0’) , в Decimal(‘0e0’) . Используется для создания канонических значений атрибутов класса эквивалентности. Например, Decimal(‘32.100’) и Decimal(‘0.321000e+2’) оба нормализуются до эквивалентного значения Decimal(‘32.1’) .

Возвращает строку, определяющую class операнда. Возвращаемое значение — одна из следующих десяти строк.

  • «-Infinity» , что указывает на отрицательную бесконечность.
  • «-Normal» , указывает, что операнд является отрицательным нормальным числом.
  • «-Subnormal» , указывает, что операнд отрицательный и субнормальный.
  • «-Zero» , указывает, что операнд — отрицательный ноль.
  • «+Zero» , указывает, что операнд является положительным нулем.
  • «+Subnormal» , что указывает на то, что операнд является положительным и субнормальным.
  • «+Normal» , указывает, что операнд является положительным нормальным числом.
  • «+Infinity» , указывает, что операнд положительная бесконечность.
  • «NaN» , указывает, что операнд является тихим NaN (не числом).
  • «sNaN» , указывает, что операнд является сигнальным NaN.

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

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

В отличие от других операций, если длина коэффициента после операции квантования будет больше, чем точность, то выдаётся сигнал InvalidOperation . Это гарантирует, что, если нет состояния ошибки, квантованная экспонента всегда равна показателю правого операнда.

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

Если показатель степени второго операнда больше, чем показатель первого, может потребоваться округление. В этом случае режим округления определяется аргументом rounding , если он задан, иначе заданным аргументом context ; если ни один аргумент не указан, используется режим округления контекста текущего потока.

Возвращается ошибка всякий раз, когда результирующая экспонента больше Emax или меньше Etiny .

Возвращает Decimal(10) , основание системы счисления, в которой класс Decimal выполняет всю свою арифметику. Включён для совместимости со спецификацией.

remainder_near ( other, context=None ) ¶

Возвращает остаток от деления self на other. Это отличается от self % other тем, что знак остатка выбран так, чтобы минимизировать его абсолютное значение. Точнее, возвращаемое значение — self — n * other , где n — целое число, ближайшее к точному значению self / other , и если два целых числа одинаково близки, то выбирается чётное.

Если результат равен нулю, то его знаком будет знак self.

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

rotate ( other, context=None ) ¶

Возвращает результат поворота цифр первого операнда на величину, указанную вторым операндом. Второй операнд должен быть целым числом в диапазоне от точности до точности. Абсолютное значение второго операнда дает количество мест для поворота. Если второй операнд положительный, вращение осуществляется влево; в противном случае вращение идёт вправо. При необходимости коэффициент первого операнда дополняется слева нулями с точностью до длины. Знак и показатель степени первого операнда не меняются.

same_quantum ( other, context=None ) ¶

Проверить, одинаковы ли у себя и у других одинаковый показатель степени или оба они равны NaN .

Операция не зависит от контекста и выполняется тихо: флаги не меняются и округление не выполняется. В качестве исключения версия C может вызвать InvalidOperation, если второй операнд не может быть точно преобразован.

Возвращает первый операнд с показателем, скорректированным вторым. Точно так же возвращает первый операнд, умноженный на 10**other . Второй операнд должен быть целым числом.

Возвращает результат сдвига цифр первого операнда на величину, указанную вторым операндом. Второй операнд должен быть целым числом в диапазоне от точности до точности. Абсолютное значение второго операнда предоставляет количество мест для сдвига. Если второй операнд положительный, то сдвиг влево; в противном случае сдвиг вправо. Цифры сдвинутые в коэффициент равны нулю. Знак и показатель степени первого операнда не меняются.

Возвращает квадратный корень аргумента с полной точностью.

Преобразовать в строку, используя инженерные обозначения, если требуется показатель степени.

В инженерной нотации показатель степени кратен 3. При этом слева от десятичного разряда может оставаться до 3 цифр, а также может потребоваться добавление одного или двух нулей в конце.

Например, преобразует Decimal(‘123E+1’) в Decimal(‘1.23E+3’) .

to_integral ( rounding=None, context=None ) ¶

Идентично методу to_integral_value() . Имя to_integral было сохранено для совместимости со старыми версиями.

to_integral_exact ( rounding=None, context=None ) ¶

Округлить до ближайшего целого числа, сигнализируя Inexact или Rounded , если округление происходит. Режим округления определяется параметром rounding , если он задан, иначе заданным context . Если ни один параметр не указан, используется режим округления текущего контекста.

to_integral_value ( rounding=None, context=None ) ¶

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

Логические операнды¶

Методы logical_and() , logical_invert() , logical_or() и logical_xor() ожидают, что их аргументы будут логическими операндами. Логический операнд — это экземпляр Decimal , показатель степени и знак которого равны нулю, а все цифры — 0 или 1 .

Объекты контекста¶

Контексты — это среда для арифметических операций. Они регулируют точность, устанавливают правила округления, определяют, какие сигналы обрабатываются как исключения, и ограничивают диапазон показателей.

У каждого потока есть свой текущий контекст, доступ к которому или его изменение осуществляется с помощью функций getcontext() и setcontext() :

Возвращает текущий контекст для активного потока.

decimal. setcontext ( c ) ¶

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

Вы также можете использовать оператор with и функцию localcontext() для временного изменения активного контекста.

decimal. localcontext ( ctx=None ) ¶

Возвращает менеджер контекста, который установит текущий контекст для активного потока на копию ctx при входе в оператор with и восстановит предыдущий контекст при выходе из оператора with. Если контекст не указан, используется копия текущего контекста.

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

from decimal import localcontext with localcontext() as ctx: ctx.prec = 42 # Выполните расчет с высокой точностью s = calculate_something() s = +s # Округление окончательный результат до точности по умолчанию 

Новые контексты также могут быть созданы с помощью конструктора Context , описанного ниже. Кроме того, модуль предоставляет три готовых контекста:

class decimal. BasicContext ¶

Это стандартный контекст, определенный общей спецификацией десятичной арифметики. Точность установлена на девять. Для округления установлено значение ROUND_HALF_UP . Все флаги сняты. Все прерывания включены (рассматриваются как исключения), кроме Inexact , Rounded и Subnormal .

Поскольку многие ловушки включены, этот контекст полезен для отладки.

class decimal. ExtendedContext ¶

Это стандартный контекст, определенный общей спецификацией десятичной арифметики. Точность установлена на девять. Для округления установлено значение ROUND_HALF_EVEN . Все флаги сняты. Никакие ловушки не включены (так что исключения не возникают во время вычислений).

Поскольку ловушки отключены, этот контекст полезен для приложений, которые предпочитают содержать значение результата NaN или Infinity вместо создания исключений. Это позволяет приложению завершить выполнение при наличии условий, которые в противном случае остановили бы программу.

class decimal. DefaultContext ¶

Этот контекст используется конструктором Context в качестве прототипа для новых контекстов. Изменение поля (такой точности) приводит к изменению значения по умолчанию для новых контекстов, созданных конструктором Context .

Этот контекст наиболее полезен в многопоточных средах. Изменение одного из полей перед запуском потоков приводит к установке общесистемных значений по умолчанию. Изменять поля после запуска потоков не рекомендуется, т. к. это потребует синхронизации потоков для предотвращения состояния гонки.

В однопоточных средах предпочтительно вообще не использовать этот контекст. Вместо этого просто создать контексты явно, как описано ниже.

Значения по умолчанию: prec = 28 , rounding = ROUND_HALF_EVEN , а ловушки включены для Overflow , InvalidOperation и DivisionByZero .

В дополнение к трём предоставленным контекстам новые контексты могут быть созданы с помощью конструктора Context .

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

Создаёт новый контекст. Если поле не указано или None , значения по умолчанию копируются из DefaultContext . Если поле flags не указано или равно None , все флаги сброшены.

prec — это целое число в диапазоне [ 1 , MAX_PREC ], которое устанавливает точность для арифметических операций в контексте.

Параметр rounding — одна из констант, перечисленных в разделе Режимы округления.

В полях traps и flags перечислены все сигналы, которые необходимо установить. Как правило, новые контексты должны только устанавливать ловушки и оставлять флаги снятыми.

Поля Emin и Emax представляют собой целые числа, определяющие внешние пределы, допустимые для экспонент. Emin должен находиться в диапазоне [ MIN_EMIN , 0 ], Emax — в диапазоне [ 0 , MAX_EMAX ].

Поле capitals может быть 0 или 1 (по умолчанию). Если установлено значение 1 , экспоненты печатаются с заглавной буквы E ; в противном случае используется строчная буква e : Decimal(‘6.02e+23’) .

Поле clamp — это либо 0 (по умолчанию), либо 1 . Если установлено значение 1 , показатель степени e экземпляра Decimal , представленного в этом контексте, строго ограничен диапазоном Emin — prec + 1 clamp — это 0 , то выполняется более слабое условие: скорректированная экспонента экземпляра Decimal не превышает Emax . Когда clamp равно 1 , у большого нормального числа, где это возможно, будет уменьшена экспонента и к его коэффициенту добавлено соответствующее количество нулей, чтобы соответствовать ограничениям экспоненты; это сохраняет значение числа, но теряет информацию о значимых конечных нулях. Например:

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

Значение clamp для 1 обеспечивает совместимость с десятичными форматами обмена фиксированной ширины, указанными в IEEE 754.

Класс Context определяет несколько методов общего назначения, а также большое количество методов для выполнения арифметических операций непосредственно в заданном контексте. Кроме того, для каждого из описанных выше методов Decimal (за исключением методов adjusted() и as_tuple() ) существует соответствующий метод Context . Например, для экземпляра Context C и экземпляра Decimal x C.exp(x) эквивалентно x.exp(context=C) . Каждый метод Context принимает целое число Python (экземпляр int ) везде, где принимается экземпляр Decimal.

Сбрасывает все флаги на 0 .

Сбрасывает все ловушки на 0 .

Добавлено в версии 3.3.

Возвращает дубликат контекста.

Возвращает копию Decimal экземпляра num.

Создаёт новый экземпляр Decimal из num, но с использованием self в качестве контекста. В отличие от конструктора Decimal , к преобразованию применяются точность контекста, метод округления, флаги и ловушки.

Это полезно, потому что константы часто задаются с большей точностью, чем требуется приложению. Ещё одно преимущество заключается в том, что округление немедленно устраняет непредвиденные эффекты от цифр, превышающих текущую точность. В следующем примере использование неокругленных входных значений означает, что добавление нуля к сумме может изменить результат:

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

Этот метод реализует операцию к номеру спецификации IBM. Если аргумент является строкой, не допускаются начальные и конечные пробелы или символы подчёркивания.

Создаёт новый экземпляр Decimal из числа с плавающей запятой f, но с округлением с использованием self в качестве контекста. В отличие от метода класса Decimal.from_float() , к преобразованию применяются точность контекста, метод округления, флаги и ловушки.

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

Добавлено в версии 3.1.

Возвращает значение, равное Emin — prec + 1 , которое является минимальным значением экспоненты для субнормальных результатов. Когда происходит потеря значимости, показатель степени устанавливается равным Etiny .

Возвращает значение, равное Emax — prec + 1 .

Обычный подход к работе с десятичными знаками заключается в создании экземпляров Decimal и последующем применении арифметических операций, которые выполняются в текущем контексте для активного потока. Альтернативный подход — использовать контекстные методы для вычислений в заданном контексте. Данные методы аналогичны методам для класса Decimal и здесь кратко рассмотрены.

Возвращает абсолютное значение x.

Возвращает сумму x и y.

Возвращает тот же объект Decimal x.

Сравнивает x и y численно.

Сравнивает численно значения двух операндов.

Сравнивает два операнда, используя их абстрактное представление.

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

Возвращает копию x со знаком 0.

Возвращает копию x с перевернутым знаком.

Копирует знак из y в x.

Возвращает x, делённое на y.

Возвращает x, делённое на y, усеченное до целого числа.

Делит два числа и возвращает целую часть результата.

Возвращает e ** x .

Возвращает x, умноженное на y, плюс z.

Возвращает True , если x является каноническим; в противном случае возвращает False .

Возвращает True , если x конечно; в противном случае возвращает False .

Возвращает True , если x бесконечно; в противном случае возвращает False .

Возвращает True , если x является qNaN или sNaN; в противном случае возвращает False .

Возвращает True , если x — нормальное число; в противном случае возвращает False .

Возвращает True , если x — тихий NaN; в противном случае возвращает False .

Возвращает True , если x отрицательно; в противном случае возвращает False .

Возвращает True , если x является сигнальным NaN; в противном случае возвращает False .

Возвращает True , если x отклоняется от нормы; в противном случае возвращает False .

Возвращает True , если x — ноль; в противном случае возвращает False .

Возвращает натуральный логарифм (с основанием е) x.

Возвращает десятичный логарифм x.

Возвращает показатель степени MSD операнда.

Применяет логическую операцию и между цифрами каждого операнда.

Инвертирует все цифры в x.

Применяет логическую операцию или между цифрами каждого операнда.

Применяет логическую операцию xor между цифрами каждого операнда.

Сравнивает два значения численно и возвращает максимальное значение.

Сравнивает числовые значения, игнорируя их знак.

Сравнивает два значения численно и возвращает минимум.

Сравнивает числовые значения, игнорируя их знак.

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

Возвращает умножение x и y.

Возвращает наибольшее представимое число меньше x.

Возвращает наименьшее представимое число больше x.

Возвращает число, ближайшее к x в направлении y.

Преобразует x в простейшую форму.

Возвращает указание класса x.

Плюс соответствует оператору унарного префикса плюс в Python. Эта операция применяет точность контекста и округление, поэтому это не операция идентификации.

Возвращает x в степени y , уменьшив по модулю modulo , если он задан.

С двумя аргументами вычислит x**y . Если x отрицательное, тогда y должно быть целым. Результат будет неточным, если y не является целым, а результат конечным и может быть точно выражен цифрами «точности». Используется режим округления контекста. В версии Python результаты всегда округляются правильно.

Decimal(0) ** Decimal(0) приводит к InvalidOperation , а если InvalidOperation не захватывается, то отдаёт Decimal(‘NaN’) .

Изменено в версии 3.3: Модуль C вычисляет power() в терминах правильно округленных функций exp() и ln() . Результат чётко определен, но только «почти всегда правильно округлён».

С тремя аргументами вычисляет (x**y) % modulo . Для формы с тремя аргументами имеют место следующие ограничения на аргументы:

  • все три аргумента должны быть целыми.
  • y должен быть неотрицательным
  • по крайней мере, один из x или y должен быть ненулевым.
  • modulo должен быть ненулевым и содержать не более «точных» цифр

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

Возвращает значение, равное x (округленное), с показателем степени y.

Просто возвращает 10, т. к. это Decimal 🙂

Возвращает остаток от целочисленного деления.

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

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

Возвращает повернутую копию x, y раз.

Возвращает True , если у двух операндов одинаковая степень.

Возвращает первый операнд после добавления второго значения его exp.

Возвращает сдвинутую копию x, y раз.

Квадратный корень из неотрицательного числа с точностью до контекста.

Возвращает разницу между x и y.

Преобразовать в строку, используя инженерные обозначения, если требуется показатель степени.

В инженерной нотации показатель степени кратен 3. При этом слева от десятичного разряда может оставаться до 3 цифр, а также может потребоваться добавление одного или двух нулей в конце.

Округляет до целого числа.

Преобразует число в строку с использованием экспоненциальной записи.

Константы¶

Константы в этом разделе актуальны только для модуля C. Они также включены в чистую версию Python для совместимости.

32-bit 64-bit
decimal. MAX_PREC ¶ 425000000 999999999999999999
decimal. MAX_EMAX ¶ 425000000 999999999999999999
decimal. MIN_EMIN ¶ -425000000 -999999999999999999
decimal. MIN_ETINY ¶ -849999999 -1999999999999999997

decimal. HAVE_THREADS ¶

Значение — True . Устарело, потому что у Python теперь всегда есть потоки.

Не рекомендуется, начиная с версии 3.9.

decimal. HAVE_CONTEXTVAR ¶

Значение по умолчанию — True . Если Python скомпилирован как —without-decimal-contextvar , версия C использует локальный поток, а не локальный контекст сопрограммы, и значение равно False . Это немного быстрее в некоторых сценариях вложенного контекста.

Добавлено в версии 3.9: перенесён на 3.7 и 3.8

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

decimal. ROUND_CEILING ¶

Округлить в сторону Infinity .

Округлить в сторону нуля.

Округлить в сторону -Infinity .

Округлить до ближайшего с приближением к нулю.

Округлить до ближайшего с переходом к ближайшему чётному целому числу.

Округлить до ближайшего с уходом от нуля.

Округлить от нуля.

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

Сигналы¶

Сигналы представляют собой условия, возникающие во время вычислений. Каждому соответствует один флаг контекста и один активатор контекстной ловушки.

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

Если для сигнала установлен активатор прерывания контекста, то условие вызывает исключение Python. Например, если установлено прерывание DivisionByZero , то при обнаружении условия возникает исключение DivisionByZero .

class decimal. Clamped ¶

Изменён показатель степени, чтобы соответствовать ограничениям представления.

Обычно ограничение происходит, когда показатель степени выходит за пределы контекста Emin и Emax . Если возможно, показатель степени уменьшается, добавляя к коэффициенту нули.

class decimal. DecimalException ¶

Базовый класс для других сигналов и подкласс ArithmeticError .

class decimal. DivisionByZero ¶

Сообщает о делении небесконечного числа на ноль.

Может происходить при делении, делении по модулю или при возведении числа в отрицательную степень. Если этот сигнал не перехвачен, возвращает Infinity или -Infinity со знаком, определенным входными данными для вычисления.

class decimal. Inexact ¶

Указывает, что произошло округление и результат неточный.

Сигналы, когда при округлении отбрасывались ненулевые цифры. Возвращается округленный результат. Флаг сигнала или ловушка используются для обнаружения неточных результатов.

class decimal. InvalidOperation ¶

Выполнена недопустимая операция.

Указывает, что была запрошена операция, которая не имеет смысла. Если ловушка не обнаружена, возвращает NaN . Возможные причины включают:

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

class decimal. Overflow ¶

Указывает, что показатель степени больше Emax после того, как произошло округление. Если не захвачен, результат зависит от режима округления: либо оттягивание внутрь до наибольшего представимого конечного числа, либо от округления до Infinity . В любом случае также сигнализируются Inexact и Rounded .

class decimal. Rounded ¶

Произошло округление, хотя, возможно, информация не была потеряна.

Сигнализирует, когда округление отбрасывает цифры; даже если эти цифры равны нулю (например, округление 5.00 до 5.0 ). Если не захвачен, возвращает результат без изменений. Этот сигнал используется для обнаружения потери значащих цифр.

class decimal. Subnormal ¶

До округления экспонента была ниже, чем Emin .

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

class decimal. Underflow ¶

Исчезновение числового значения с округлением до нуля.

Происходит, когда субнормальный результат сбрасывается до нуля путём округления. Также сигнализируются Inexact и Subnormal .

class decimal. FloatOperation ¶

Включите более строгую семантику для смешивания чисел с плавающей запятой и десятичных знаков.

Если сигнал не перехвачен (по умолчанию), в конструкторе Decimal , create_decimal() и всех операторах сравнения разрешено смешивание чисел с плавающей запятой и десятичных знаков. И преобразование, и сравнение точны. Любое появление смешанной операции автоматически записывается путём установки FloatOperation в контекстных флагах. Явные преобразования с from_float() или create_decimal_from_float() не устанавливают флаг.

В противном случае (сигнал перехвачен) молчат только сравнения на равенство и явные преобразования. Все другие смешанные операции поднимают FloatOperation .

В следующей таблице приведена иерархия сигналов:

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

Примечания о плавающей точке¶

Уменьшение ошибки округления с повышенной точностью¶

Использование десятичного числа с плавающей точкой устраняет ошибку десятичного представления (что позволяет точно представить 0.1 ); однако некоторые операции могут по-прежнему вызывать ошибку округления, если ненулевые цифры превышают фиксированную точность.

Эффект ошибки округления может быть усилен путём добавления или вычитания почти компенсирующих величин, что приводит к потере значимости. Кнут приводит два поучительных примера, где округленная арифметика с плавающей точкой с недостаточной точностью приводит к нарушению ассоциативных и распределительных свойств сложения:

# Примеры из Получисловые алгоритмы, раздел 4.2.2. >>> from decimal import Decimal, getcontext >>> getcontext().prec = 8 >>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111') >>> (u + v) + w Decimal('9.5111111') >>> u + (v + w) Decimal('10') >>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003') >>> (u*v) + (u*w) Decimal('0.01') >>> u * (v+w) Decimal('0.0060000') 

Модуль decimal позволяет восстанавливать идентификационные данные, увеличивая точность в достаточной степени, чтобы избежать потери значимости:

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

Особые значения¶

Система счисления для модуля decimal предоставляет специальные значения, включая NaN , sNaN , -Infinity , Infinity и два нуля, +0 и -0 .

Бесконечности можно построить напрямую с помощью: Decimal(‘Infinity’) . Кроме того, они могут возникать при делении на ноль, когда сигнал DivisionByZero не перехвачен. Точно так же, когда сигнал Overflow не перехвачен, бесконечность может возникнуть в результате округления за пределами наибольшего представимого числа.

Бесконечности подписаны (аффинны) и могут использоваться в арифметических операциях, где они рассматриваются как очень большие неопределенные числа. Например, добавление константы к бесконечности даёт еще один бесконечный результат.

Некоторые операции являются неопределенными и возвращают NaN , или, если сигнал InvalidOperation перехватывается, вызывает исключение. Например, 0/0 возвращает NaN , что означает «не число». Эта разновидность NaN тиха и после создания будет проходить через другие вычисления, всегда приводя к другому NaN . Такое поведение может быть полезно для серии вычислений, в которых иногда отсутствуют входные данные. Это позволяет продолжить вычисления, отмечая определенные результаты как недопустимые.

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

Поведение операторов сравнения Python может быть немного удивительным, когда задействован NaN . Проверка на равенство, когда один из операндов является тихим или сигнализирующим, NaN всегда возвращает False (даже при выполнении Decimal(‘NaN’)==Decimal(‘NaN’) ), а проверка на неравенство всегда возвращает True . Попытка сравнить два десятичных знака с использованием любого из операторов < , или >= вызовет сигнал InvalidOperation , если один из операндов является NaN , и вернёт False , если этот сигнал не перехвачен. Обратите внимание, что спецификация общей десятичной арифметики не определяет поведение прямых сравнений; эти правила сравнения с использованием NaN были взяты из стандарта IEEE 854 (см. таблицу 3 в разделе 5.7). Чтобы обеспечить строгое соответствие стандартам, использовать вместо них методы compare() и compare-signal() .

Знаки нулей могут быть результатом вычислений, которые не выполняются. Они сохраняют знак, который был бы получен, если бы расчет был проведен с большей точностью. Поскольку их величина равна нулю, положительные и отрицательные нули считаются равными, а их знак является информационным.

В дополнение к двум знаковым нулям, которые различны, но равны, существуют различные представления нуля с разной точностью, но эквивалентные по значению. К этому нужно немного привыкнуть. Для глаза, привыкшего к нормализованным представлениям с плавающей запятой, не сразу очевидно, что следующее вычисление возвращает значение, равное нулю:

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

Работа с потоками¶

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

Точно так же функция setcontext() автоматически назначает свою цель текущему потоку.

Если setcontext() не был вызван до getcontext() , то getcontext() автоматически создаст новый контекст для использования в текущем потоке.

Новый контекст копируется из контекста прототипа под названием DefaultContext. Чтобы управлять значениями по умолчанию, чтобы каждый поток использовал одни и те же значения во всем приложении, напрямую измените объект DefaultContext. Это должно быть выполнено перед запуском всех потоков, чтобы не было состояния гонки между потоками, вызывающими getcontext() . Например:

# Установить значения по умолчанию для всех потоков, которые будут запущены DefaultContext.prec = 12 DefaultContext.rounding = ROUND_DOWN DefaultContext.traps = ExtendedContext.traps.copy() DefaultContext.traps[InvalidOperation] = 1 setcontext(DefaultContext) # После этого можно запускать потоки t1.start() t2.start() t3.start() . . . 

Рецепты¶

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

def moneyfmt(value, places=2, curr='', sep=',', dp='.', pos='', neg='-', trailneg=''): """Преобразовать Decimal в денежную форматированную строку. places: необходимое количество знаков после запятой curr: необязательный символ валюты перед знаком (может быть пустым) sep: дополнительный разделитель группировки (запятая, точка, пробел или пусто) dp: индикатор десятичной точки (запятая или точка) указывать только как пустые, когда места нулевые pos: необязательный знак для положительных чисел: «+», пробел или пусто neg: необязательный знак для отрицательных чисел: '-', '(', пробел или пусто trailneg:дополнительный индикатор трейлинг минус:' -',')', пробел или пусто >>> d = Decimal('-1234567.8901') >>> moneyfmt(d, curr='$') '-$1,234,567.89' >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-') '1.234.568-' >>> moneyfmt(d, curr='$', neg='(', trailneg=')') '($1,234,567.89)' >>> moneyfmt(Decimal(123456789), sep=' ') '123 456 789.00' >>> moneyfmt(Decimal('-0.02'), neg='') '' """ q = Decimal(10) ** -places # 2 места --> '0.01' sign, digits, exp = value.quantize(q).as_tuple() result = [] digits = list(map(str, digits)) build, next = result.append, digits.pop if sign: build(trailneg) for i in range(places): build(next() if digits else '0') if places: build(dp) if not digits: build('0') i = 0 while digits: build(next()) i += 1 if i == 3 and digits: i = 0 build(sep) build(curr) build(neg if sign else pos) return ''.join(reversed(result)) def pi(): """Вычислить Пи с текущей точностью. >>> print(pi()) 3.141592653589793238462643383 """ getcontext().prec += 2 # дополнительные цифры для промежуточных шагов three = Decimal(3) # заменить "three=3.0" для регулярных флоутов lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24 while s != lasts: lasts = s n, na = n+na, na+8 d, da = d+da, da+32 t = (t * n) / d s += t getcontext().prec -= 2 return +s # унарный плюс применяется новая точность def exp(x): """Возвращает e, возведенное в степень x. Тип результата соответствует типу ввода. >>> print(exp(Decimal(1))) 2.718281828459045235360287471 >>> print(exp(Decimal(2))) 7.389056098930650227230427461 >>> print(exp(2.0)) 7.38905609893 >>> print(exp(2+0j)) (7.38905609893+0j) """ getcontext().prec += 2 i, lasts, s, fact, num = 0, 0, 1, 1, 1 while s != lasts: lasts = s i += 1 fact *= i num *= x s += num / fact getcontext().prec -= 2 return +s def cos(x): """Возвращает косинус x, измеренный в радианах. Аппроксимация рядов Тейлора лучше всего работает при малом значении X. Для больших значений сначала вычислите x = x % (2 * pi). >>> print(cos(Decimal('0.5'))) 0.8775825618903727161162815826 >>> print(cos(0.5)) 0.87758256189 >>> print(cos(0.5+0j)) (0.87758256189+0j) """ getcontext().prec += 2 i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1 while s != lasts: lasts = s i += 2 fact *= i * (i-1) num *= x * x sign *= -1 s += num / fact * sign getcontext().prec -= 2 return +s def sin(x): """Возвращает синус x, измеренный в радианах. Аппроксимация рядов Тейлора лучше всего работает при малом значении X. Для больших значений сначала вычислите x = x % (2 * pi). >>> print(sin(Decimal('0.5'))) 0.4794255386042030002732879352 >>> print(sin(0.5)) 0.479425538604 >>> print(sin(0.5+0j)) (0.479425538604+0j) """ getcontext().prec += 2 i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1 while s != lasts: lasts = s i += 2 fact *= i * (i-1) num *= x * x sign *= -1 s += num / fact * sign getcontext().prec -= 2 return +s 

Часто задаваемые вопросы по Decimal¶

Вопрос. Громоздко набирать decimal.Decimal(‘1234.5’) . Есть ли способ минимизировать ввод при использовании интерактивного интерпретатора?

Ответ. Некоторые пользователи сокращают конструктор только одной буквой:

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

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

Ответ. Метод quantize() округляется до фиксированного числа десятичных разрядов. Если задана ловушка Inexact , она также полезна для проверки:

>>> TWOPLACES = Decimal(10) ** -2 # некоторый Decimal('0.01') 
>>> # Округлить до двух знаков >>> Decimal('3.214').quantize(TWOPLACES) Decimal('3.21') 
>>> # Убедитесь, что число не превышает двух мест >>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact])) Decimal('3.21') 
>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact])) Traceback (most recent call last): . Inexact: None 

Вопрос. Когда у меня есть действительные два места ввода, как мне сохранить этот инвариант во всем приложении?

Ответ. Некоторые операции, такие как сложение, вычитание и умножение на целое число, автоматически сохраняют фиксированную точку. Другие операции, такие как деление и нецелочисленное умножение, изменят количество десятичных разрядов и должны сопровождаться шагом quantize() :

>>> a = Decimal('102.72') # Начальные значения с фиксированной точкой >>> b = Decimal('3.17') >>> a + b # Дополнение сохраняет фиксированную точку Decimal('105.89') >>> a - b Decimal('99.55') >>> a * 42 # Так же как и целочисленное умножение Decimal('4314.24') >>> (a * b).quantize(TWOPLACES) # Должен квантовать нецелое умножение Decimal('325.62') >>> (b / a).quantize(TWOPLACES) # И квантовать деление Decimal('0.03') 

При разработке приложений с фиксированной точкой удобно определять функции для обработки шага quantize() :

>>> def mul(x, y, fp=TWOPLACES): . return (x * y).quantize(fp) >>> def div(x, y, fp=TWOPLACES): . return (x / y).quantize(fp) 
>>> mul(a, b) # Автоматически сохранять фиксированную точку Decimal('325.62') >>> div(b, a) Decimal('0.03') 

Вопрос. Есть много способов выразить одно и то же значение. Номера 200 , 200.000 , 2E2 и 02E+4 у всех есть тот же значение в различной точности. Есть ли способ преобразовать их к единому узнаваемому каноническому значению?

Ответ. Метод normalize() сопоставляет все эквивалентные значения одному представителю:

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

Вопрос. Некоторые десятичные значения всегда печатаются с экспоненциальной нотацией. Есть ли способ получить неэкспоненциальное представление?

А. Для некоторых значения экспоненциальная нотация является единственным способом выражения числа значимых мест в коэффициенте. Например, выражение 5.0E+3 как 5000 сохраняет значение постоянной, но не может показать значение оригинала в двух позициях.

Если приложение не заботится об отслеживании значимости, легко удалить экспонентные и конечные нули, потеряв значимость, но сохранив значение неизменным:

>>> def remove_exponent(d): . return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize() 
>>> remove_exponent(Decimal('5E+3')) Decimal('5000') 

Вопрос. Есть ли способ преобразовать обычный float в Decimal ?

Ответ. Да, любое двоичное число с плавающей точкой может быть точно выражено как десятичное, хотя точное преобразование может занять больше точности, чем подсказывает интуиция:

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

Вопрос. В рамках сложных расчётов, как я могу убедиться, что я не получил ложный результат из-за недостаточной точности или аномалий округления.

Ответ. Модуль decimal упрощает проверку результатов. Оптимальным вариантом является повторный запуск вычислений с большей точностью и с различными режимами округления. Широко различающиеся результаты указывают на недостаточную точность, проблемы режима округления, неполноценные входные данные или численно нестабильный алгоритм.

Вопрос. Я заметил, что точность контекста применяется к результатам операций, но не на входы. Есть ли что-то, на что следует обратить внимание при смешивании значений разных точностей?

Ответ. Да. Принцип заключается в том, что все значения считаются точными и поэтому арифметика этих значений. Только результаты округляются. Преимущество для входных данных — это то, что вы печатаете, то и получаете. Недостатком является то, что результаты могут выглядеть странно, если вы забудете, что входные данные не были округлены:

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

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

>>> getcontext().prec = 3 >>> +Decimal('1.23456789') # унарный плюс запускает округление Decimal('1.23') 

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

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

Вопрос. Быстрая ли реализация CPython для больших чисел?

Ответ. Да. В реализациях CPython и PyPy3 версии C/CFFI Decimal модуля интегрируют высокоскоростную библиотеку libmpdec для произвольной точности правильного округленной десятичной арифметики с плавающей точкой. libmpdec использует умножение Карацуба для средних чисел и Теоретическое преобразование числа для очень больших чисел.

>>> c = getcontext() >>> c.prec = MAX_PREC >>> c.Emax = MAX_EMAX >>> c.Emin = MIN_EMIN 

Добавлено в версии 3.3.

Использование модуля decimal в Python

Использование модуля decimal в Python

В данном руководстве мы рассмотрим использование модуля для работы с десятичными числами, который включен в стандартную библиотеку Python.

Введение

В Python есть числовые типы данных, такие как int, float и комплексные числа, но из-за машинной зависимости чисел с плавающей точкой нам нужен более точный тип данных для вычислений, требующих высокой точности. В этой статье мы рассмотрим модуль decimal в Python, который реализует десятичные числа с точностью до 28 цифр.

Использование

Python реализует десятичные числа как числа двойной точности с плавающей точкой, которые зависят от машины. Для вычислений, где точность критична для бизнеса, числа с плавающей точкой могут вызывать ошибки при выполнении на другой машине. Поэтому для таких приложений нам нужен независимый от машины тип данных для реализации десятичных чисел, который был реализован с помощью модуля decimal в Python. Кроме того, модуль decimal реализует десятичное число с точностью до 28 десятичных цифр, в то время как числа с плавающей запятой имеют точность до 18 цифр.

Это можно наблюдать в следующем примере

import decimal float_num = 100 / 3 print(float_num) decimal_num = decimal.Decimal(100) / decimal.Decimal(3) print(decimal_num)
33.333333333333336 33.33333333333333333333333333

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

Из-за аппроксимации значения с плавающей точкой дают разные результаты для разных вычислений. Например, если мы сложим 1,2 и 2,2, используя значения с плавающей точкой, ответ должен быть равен 3,4. Но когда мы сравним добавленное число и 3,4, они не будут равны. Эта ошибка возникает из-за приближений в числах с плавающей запятой, из-за которых сумма 1,2 и 2,2 не равна 3,4.

Поэтому в случаях, когда необходимо сравнить десятичные значения, следует использовать десятичный модуль, а не числа с плавающей точкой.

Это может быть более понятно из следующего примера.

a = 1.2 b = 2.2 c = 3.4 d = a + b print("a:", a) print("b:", b) print("c:", c) print("a+b:", d) print("a+b==c?:", d == c)
a: 1.2 b: 2.2 c: 3.4 a+b: 3.4000000000000004 a+b==c?: False

Настройка контекста

Чтобы использовать модуль decimal в Python, достаточно его импортировать следующим образом.

import decimal

Импортированный модуль имеет предопределенный контекст, который содержит значения по умолчанию для точности, округления, флагов, минимально и максимально допустимых чисел. Мы можем посмотреть значения контекста с помощью метода getcontext() следующим образом.

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

Мы также можем установить точность и другие параметры контекста. Чтобы изменить точность на 2 цифры вместо 28, мы можем использовать следующую программу.

import decimal decimal.getcontext().prec = 2 print(decimal.getcontext())
Context(prec=2, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])

По умолчанию, при округлении десятичных чисел с помощью модуля decimal, числа округляются равномерно. Мы можем изменить это поведение, изменив значение «rounding» в контексте следующим образом.

import decimal decimal.getcontext().rounding = "ROUND_HALF_DOWN" print(decimal.getcontext())
Context(prec=28, rounding=ROUND_HALF_DOWN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])

Все арифметические операции над десятичными числами, определяемые модулем decimal, аналогичны операциям над числами с плавающей запятой. Разница заключается в точности значений из-за различий в реализации.

Округление значений

Мы можем округлять числа до определенных цифр с помощью функции round(). Функция round принимает десятичное число, которое нужно округлить, в качестве первого аргумента и количество цифр, до которых его нужно округлить, в качестве второго аргумента и возвращает округленное десятичное значение следующим образом.

import decimal num1 = decimal.Decimal(100) num2 = decimal.Decimal(3) print("Первое число:", num1) print("Второе число:", num2) num3 = num1 / num2 print("Первое число разделенное на второе число:", num3) num4 = round(num3, 2) print("Округленное число:", num4)
Первое число: 100 Второе число: 3 Первое число разделенное на второе число: 33.33333333333333333333333333 Округленное число: 33.33

Сравнение десятичных чисел

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

import decimal a = decimal.Decimal("1.2") b = decimal.Decimal("2.2") c = decimal.Decimal("3.4") d = a + b print("a:", a) print("b:", b) print("c:", c) print("a+b:", d) print("a+b==c?:", c == d)
a: 1.2 b: 2.2 c: 3.4 a+b: 3.4 a+b==c?: True

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

Заключение

В этой статье мы изучили недостатки выполнения арифметических операций с числами с плавающей точкой и использовали модуль decimal для реализации тех же операций без ошибок в Python. Мы также можем написать программы, использованные в этой статье, с обработкой исключений, используя python try except, чтобы сделать программы более надежными и систематически обрабатывать ошибки.

Оставайтесь с нами для получения новых информативных статей.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *