Как установить decimal python
Перейти к содержимому

Как установить decimal python

  • автор:

Как установить 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 в 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

Скачай курс
в приложении

Перейти в приложение
Открыть мобильную версию сайта

© 2013 — 2023. Stepik

Наши условия использования и конфиденциальности

Get it on Google Play

Public user contributions licensed under cc-wiki license with attribution required

Числа с фиксированной точностью. Класс Decimal

Числа с фиксированной точностью – это числа типа Decimal , которые при вычислениях используют фиксированное количество знаков после запятой. Тип Decimal – это специально разработанный класс (начиная с версии Python 2.4).

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

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

Класс Decimal реализован в модуле decimal . Чтобы использовать возможности класса Decimal нужно выполнить команду

from decimal import Decimal
2. Как с помощью класса Decimal задать нужную фиксированную точность? Примеры

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

Decimal('0.002') # фиксированная точность 3 знака после запятой Decimal('0.23') # фиксированная точность 2 знака после запятой Decimal('0.00001') # фиксированная точность 5 знаков после запятой
3. Пример необходимости применения класса Decimal в программах на Python

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

# Числа с фиксированной точностью. Класс Decimal - преимущества применения # подключить класс Decimal из модуля decimal from decimal import Decimal # обычное вычисление, существует погрешность a = 0.2+0.2+0.2-0.4 # a = 0.20000000000000007 - погрешность (. ) print('a = ', a) # вычисление с помощью класса Decimal b = Decimal('0.2')+Decimal('0.2')+Decimal('0.2')-Decimal('0.4') print('b = ', b) # b = 0.2 - точный результат

Результат работы программы

a = 0.20000000000000007 b = 0.2

Сначала создается объект (переменная) с именем a , в которую записывается сумма

0.2+0.2+0.2–0.4

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

На следующем шаге создается объект с именем b , в который записывается сумма с использованием класса Decimal

b = Decimal('0.2')+Decimal('0.2')+Decimal('0.2')-Decimal('0.4')

После вывода значения b на экран, видно что значение переменной b представлено точно без погрешности.

4. Пример использования класса Decimal и функции str()

В предыдущем примере конструктор класса Decimal получал строку с числом

Decimal('0.2')

в котором определялась точность (1 знак после запятой) и значение числа 0.2.

Возможна ситуация, когда нужно передать непосредственно число а не строку. В этом случае удобно использовать функцию str() , как показано ниже

# вычисление с помощью класса Decimal b = Decimal(str(0.2))+Decimal(str(0.2))+Decimal(str(0.2))-Decimal(str(0.4)) print('b = ', b) # b = 0.2

Функция str() получает число и переводит его в строку

x = str(0.2) # x = '0.2'
5. Использование фиксированной точности для чисел с разной точностью представлений. Пример

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

Например. При сложении трех чисел

c = Decimal('0.1')+Decimal('0.001')+Decimal(str(0.01)) # c = 0.111

автоматически устанавливается точность 3 знака после запятой, поскольку конструктор

Decimal('0.001')

определяет число 0.001 с наибольшей точностью представления.

6. Создание объектов класса Decimal из вещественных чисел. Пример

Для случаев, когда есть в наличии вещественное число, можно создать объект класса Decimal . В этом случае используется метод from_float() класса Decimal .

# Создание объекта типа Decimal, не всегда работает # Случай 1. Искаженная точность # x1 = 2.479999999999999982236431605997495353221893310546875 x1 = Decimal.from_float(2.48) print('x1 =',x1) # Случай 2. Фиксированная точность x2 = Decimal.from_float(2.5) # x2 = 2.5 - правильная точность print('x2 =', x2)

Результат выполнения вышеприведенного кода

x1 = 2.479999999999999982236431605997495353221893310546875 x2 = 2.5

Как видно из результата, не всегда удается получить фиксированную точность при использовании метода from_float() .

7. Глобальная настройка точности. Пример

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

Пример.

# Глобальное задание точности # подключить класс Decimal from decimal import Decimal a = Decimal(5)/Decimal(13) # точность не задана print('a = ', a) # a = 0.3846153846153846153846153846 # задание точности 6 знаков после запятой import decimal decimal.getcontext().prec=6 b = Decimal(5)/Decimal(13) print('b = ', b) # b = 0.384615 c = Decimal(6)/Decimal(13) print('c = ', c) # c = 0.461538

Результат выполнения программы

a = 0.3846153846153846153846153846 b = 0.384615 c = 0.461538

В вышеприведенном примере глобальная точность для класса Decimal задается с помощью функции getcontext() , которая возвращает объект контекста в этом модуле. Точность задается в текущем потоке управления.

Связанные темы

  • Представление чисел разных форматов. Базовые числовые типы. Функции преобразования чисел
  • Рациональные числа. Класс Fraction

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

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