Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
Класс Decimal содержит
множество методов для выполнения различных операций над числами. Основные из
них следующие:
|
Метод
|
Описание
|
|
as_integer_ratio()
|
возвращает
кортеж (n, d) для
представления числа в виде n/d (числа n, d минимально
возможные)
|
|
as_tuple()
|
возвращает
представление вещественного числа в виде кортежа (sign, digits, exponent)
|
|
normalize()
|
возвращает
нормализованное (стандартное, единообразное) представление числа
|
|
copy_abs()
|
создание
копии объекта с модулем числа
|
|
copy_negate()
|
создание
копии объекта с противоположным знаком
|
|
copy_sign(d)
|
создание
копии объекта со знаком числа d
|
|
compare(d)
|
сравнивает
числа self и d, возвращая
значения -1 (меньше), 0 (равны), 1 (больше)
|
|
Методы проверки принадлежности
|
|
is_finite()
|
возвращает
True, если число
конечное (ограниченное) и False в противном случае (для
'Infinity' и 'NaN' возвращает False)
|
|
is_infinite()
|
возвращает
True для значения
'Infinity' и False для всех остальных
|
|
is_nan()
|
возвращает
True для значения
'NaN' и False для всех
остальных
|
|
is_normal()
|
возвращает
False для 0,
'Infinity', 'NaN' и True для всех остальных
|
|
is_signed()
|
возвращает
True для объектов
со знаком минус и False для всех остальных
|
|
is_zero()
|
возвращает
True для нулевого
значения (без учета знака: минус или плюс)
|
|
Математические методы
|
|
sqrt()
|
вычисление
квадратного корня
|
|
exp()
|
вычисление
значения экспоненты
|
|
fma(a,
b)
|
вычисление
по формуле: self * a + b
|
|
ln()
|
вычисление
натурального логарифма
|
|
log10()
|
вычисление
десятичного логарифма
|
|
max(d)
|
возвращает
наибольшее из двух чисел (self и d)
|
|
min(d)
|
возвращает
наименьшее из двух чисел (self и d)
|
|
max_mag(d)
|
возвращает
наибольшее из двух чисел (self и d) без учета
знака
|
|
min_mag(d)
|
возвращает
наименьшее из двух чисел (self и d) без учета
знака
|
|
shift(p)
|
возвращает
новый объект со смещенными цифрами на p позиций
|
|
quantize(ex)
|
выполняет
округление чисел в соответствии с указанной экспонентой ex
|
Давайте
подробнее рассмотрим работу некоторых из них. Пусть в программе имеются
следующие объекты:
a = Decimal('5.3')
b = Decimal('-655e-2')
d_inf = Decimal('Infinity')
d_nan = Decimal('NaN')
И применим
первый метод as_integer_ratio() к объекту a, получим:
a.as_integer_ratio() # (53, 10)
Возвращается
кортеж из двух чисел 53 и 10 – это числитель и знаменатель дроби для
представления числа 5.3 = 53/10.
Аналогично для
объекта b:
b.as_integer_ratio() # (-131, 20)
Знак минус
ставится у первого числа (числителя дроби). При этом числа 131 и 20 –
наименьшие (по модулю) из возможных.
Следующий метод as_tuple() мы с вами уже
подробно рассматривали на прошлом занятии, поэтому сразу перейдем к методу normalize(). Если его
вызвать для объекта b, получим его нормализованное представление:
bn = b.normalize() # Decimal('-6.55')
Следующий метод:
b_abs = b.copy_abs() # Decimal('6.55')
создает копию
объекта b с модулем числа.
Соответственно, метод copy_negate() создает копию
объекта с противоположным знаком:
a_ng = a.copy_negate() # Decimal('-5.3')
a2 = a_ng.copy_negate() # Decimal('5.3')
И последний из
этой серии позволяет задавать знак числа по другому указанному числу. Например:
res = a.copy_sign(b) # Decimal('-5.3')
Здесь знак
«минус» для числа 5.3 был взят из числа b.
Метод compare() сравнивает
два числа (объекта) Decimal, возвращая числовые значения -1, 0, 1:
a.compare(b) # Decimal('1')
a.compare(Decimal('5.3')) # Decimal('0')
b.compare(a) # Decimal('-1')
Следующая группа
методов проверок числа на различную принадлежность, работают очевидным образом.
Например:
a.is_finite() # True
d_inf.is_finite() # False
d_nan.is_finite() # False
d_inf.is_infinite() # True
d_nan.is_infinite() # False
b.is_signed() # True
a.is_signed() # False
И так далее.
Наибольший
интерес, конечно, представляют математические методы. Например:
d = Decimal(9)
res = d.sqrt() # Decimal('3')
Метод sqrt() возвращает
новый объект класса Decimal со значением квадратного корня числа d. По аналогии
работают и другие методы:
a.exp() # Decimal('200.3368099747916848352566156')
a.fma(d, b) # Decimal('41.15')
Это аналог
следующих вычислений:
res = a * d + b # Decimal('41.15')
Далее:
d.ln() # Decimal('2.197224577336219382790490474')
a.max(b) # Decimal('5.3')
a.max_mag(b) # Decimal('-6.55')
Decimal('3.1415').shift(1) # Decimal('31.4150')
Decimal('3.1415').shift(-2) # Decimal('0.0314')
Метод quantize()
Последний метод quantize() позволяет
округлять вещественные числа с заданной точностью и разными способами. В самом
простом варианте его можно записать в виде:
pi = Decimal('3.1415926535')
pi2 = pi.quantize(Decimal('.00')) # Decimal('3.14')
Здесь Decimal('.00') задает
точность (экспоненту) для округления. Можно прописывать любое вещественное
значение и метод quantize() округлит текущее число до указанного
знака. Например:
pi.quantize(Decimal('0.12')) # Decimal('3.14')
pi.quantize(Decimal('0.1234')) # Decimal('3.1416')
pi.quantize(Decimal('52.1234')) # Decimal('3.1416')
Целая часть
числа здесь не играет никакой роли. Главное, сколько значащих цифр записано
после точки.
По аналогии
можно округлить и целое число, например:
Decimal('9').quantize(Decimal('.1234')) # Decimal('9.0000')
Способы округлений чисел класса Decimal
В
действительности с числами класса Decimal можно выполнять
различные способы округлений. Они следующие:
|
Режим
округления
|
Описание
|
|
ROUND_DOWN
|
Округление
выполняется всегда вниз, независимо от последней цифры, т. е. число всегда
уменьшается или остаётся неизменным. Например:
1.5
→ 1
1.6
→ 1
|
|
ROUND_UP
|
Округление
выполняется всегда вверх, увеличивая число или оставляя его неизменным.
Например:
1.5
→ 2
1.6
→ 2
|
|
ROUND_HALF_UP
|
Традиционное
округление, известное многим как "школьное": если последняя цифра
равна или больше 5, число увеличивается, иначе остается прежним. Например:
1.5
→ 2
1.4
→ 1
|
|
ROUND_HALF_DOWN
|
Подобен
предыдущему, но округление выполняется вниз, если последняя цифра равна 5.
Например:
1.5
→ 1
1.6
→ 2
|
|
ROUND_HALF_EVEN
|
Часто
называется банковским округлением. Если последняя цифра равна 5, то округляет
число так, чтобы ближайшая целая была чётной. Например:
1.5
→ 2 (так как 2 чётное)
2.5
→ 2 (также чётное)
|
|
ROUND_CEILING
|
Подобен
ROUND_UP, но применяется только к положительным числам. Отрицательные числа
округляются в сторону нуля. Например:
1.5
→ 2
-1.5
→ -1
|
|
ROUND_FLOOR
|
Противоположность
ROUND_CEILING. Положительные числа округляются вниз, отрицательные – вверх.
Например:
1.5
→ 1
-1.5
→ -2
|
|
ROUND_05UP
|
Число
округляется только тогда, когда последняя цифра равна 0 или 5. В остальных
случаях число остается без изменений. Например:
1.05
→ 1.1
1.6
→ 1.6
|
Для определения
текущего режима округления можно выполнить следующие команды:
import decimal
context = decimal.getcontext()
round_mode = context.rounding
print(round_mode)
По умолчанию
используется ROUND_HALF_EVEN, т.е. «банковское» округление. Давайте в этом
убедимся:
Decimal('7.5').quantize(Decimal('0')) # Decimal('8')
Decimal('6.5').quantize(Decimal('0')) # Decimal('6')
Действительно
округление выполняется до ближайшего четного числа.
Чтобы поменять
режим непосредственно в методе quantize() можно воспользоваться
командой:
Decimal('6.5').quantize(Decimal('0'), rounding='ROUND_HALF_UP')
Получим значение
7, т.к. было указано «школьное» округление до ближайшего целого. И так можно
задавать любой режим.
Разумеется,
округлять можно не только до целого, но до любой желаемой точности, как это мы
видели ранее. Здесь ничего не меняется. Например:
Decimal('6.15').quantize(Decimal('0.0'), rounding='ROUND_HALF_UP')
Получим значение
6.2 по «школьному» принципу округления чисел.
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs