Битовые операции, типы данных int и float, библиотека math

Привет. В предыдущей статье про структуры данных на Python я упомянул целые числа (int) и вещественные числа (float). В этой статье  рассмотрим какие операции над числами нам доступны из коробки, ознакомимся с битовыми операциями и пройдемся по методам библиотеки math.

Если вы ранее не сталкивались с таким понятием как библиотека в Python, то краткое определение — библиотекой в Python является файл или файлы содержащие код на Python, которые мы можем импортировать в свой файл и использовать. На самом деле есть библиотеки написанные и на C, но пока просто имейте ввиду, что библиотека по сути это какой-то написанный код, который мы импортируем и используем.

Библиотека math — это библиотека написанная для выполнения расширенных математических операций над числами (за исключением комплексных числах, о которых я расскажу в будущем, но если что, комплексные числа также встроены в Pythonи для них так же есть библиотека для математических операций cmath).

Базовые возможности Python для работы с целыми и вещественными числами

Понятие целого числа знакомо каждому, кто учился в школе. Целое число — это натуральное положительное или отрицательное число и нуль. Соответственно, тип данных int может хранить в себе:

a = 10
b = 0
c = -10
print(type(a), type(b), type(c), sep = “\n“)

# Результат:
int
int
int

В Python нам доступны базовые математические операции над числами:

умножение a * b
деление a / b
сложение a + b
вычитание a – b
целочисленное деление a // b
остаток от деления a % b
смена знака числа -a
модуль числа abs(a)
пара частное и остаток, вернет кортеж divmod(a, b) будет результат a // b и a % b
возведение числа в степень a **b
ab по модулю (если модуль задан) pow(a, b[, c])

Вы можете самостоятельно проверить результат выполнения каждой операции используя стандартный вывод в консоль:

print(10 + 5)
print(10 // 2)
print(10 * 5)
.
.
.
print( 10 **2)
print(1.5 * (-2.3) // 2)

Операторы сравнения

Разумеется Python умеет сравнивать числа (нетолько числа, но и строки, об этом ниже) и результатом сравнения является возвращаемый логический тип boolean (True, False):

a > b # a больше чем b
a < b # a меньше чем b
a == b # a равно b
a != b # a не равно b
a <= b # a меньше либо равно b
a <= b # a больше либо равно b

Отмечу, что операторы == и != применимы и к строковым типам данных и к логическим, т.е. мы можем писать конструкции вида:

result = 10 == (5 + 5)
print (False == result) # получим False

string = 'Hello' != 'Hi'
print(True == string) # получим True

Именно эти операторы сравнения часто встречаются в условиях вида if … else, о них я тоже напишу в следующих статьях.

Битовые операции над числами

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

Перечень побитовых операторов:

  • побитовое ИЛИ – OR ( | )
  • побитовое исключающее ИЛИ – XOR ( ^ )
  • побитовое И – AND ( & )
  • побитовое НЕТ – NOT ( ~ )
  • побитовый сдвиг вправо >>
  • побитовый сдвиг влево <<

Сами побитовые операции производятся не над числом, а над его битовым (двоичным) представлением, над 0 и 1.

Битовый оператор AND ( | )

Производится побитовая операция на операндами по формуле где мы получаем значение для бита 1 если оба бита операндов равны 1 иначе в любом ином случае мы получаем 0.

Битовые операторы сдвига << и >>

Данная операция сдвига используется для смещения на N – количество бит в сторону:

На рисунке видно, что сдвиг влево эквивалентно умножению числа на 2, сдвиг вправо эквивалентен целочисленному делению на 2. Побитовый сдвиг существенно быстрей простой операции умножения и деления на число кратному 2 в степени N (где N это количество сдвинутых бит).

Битовый оператор ~ (NOT)

Работает над битами меняя их значения 1 на 0, а 0 на 1. Иными словами имея положительное число с применением к нему ~ мы получим отрицательное число со сдвигом -1 и наоборот от отрицательного числа придем к положительному со сдвигом -1.

print(~10)
>>> -11
print(~-10)
>>> 9

Побитовые операторы OR и XOR

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

OR — побитовое сложение где результат будет 1 если один или оба операнда равны 1 иначе мы получаем 0.

XOR — сложение по модулю 2. Мы получаем значение бита 1 только если один из битов 0, а другой 1 в остальных случаях получаем 0.

Произведем операцию XOR над числом 37 и 58 и для наглядности запишем эти числа и результат в 2 системе счисления:

a = 0 0 1 0 0 1 0 1 (3710)
b = 0 0 1 1 1 0 1 0 (5810)
a ^ b = 0 0 0 1 1 1 1 1 (3110)

Мы получили число 31 в десятичной системе как ожидали.

Библиотека math

Библиотека math встроена в Python, импортируем ее и рассмотрим какие методы у нее есть:

import math

math.ceil(x)# округление в большую сторону
math.copysign(X, Y) # вернет модуль х и знак y
math.fabs(X) # возвращает модуль заданного числа
math.factorial(X) # вернет фактариал x
math.floor(X) # округление в меньшую сторону
math.fmod(X, Y) # остаток от деления X на Y, вернет тип данных float
math.frexp(X) # возвращает мантиссу и экспоненту числа.
math.ldexp(X, I) - X * 2i.# Функция, обратная функции math.frexp().
math.fsum([1,2,3]) # сумма всех членов последовательности.
math.isfinite(X) # проверка х на то, является ли он числом.
math.isinf(X) # является ли X бесконечностью.
math.isnan(X) # является ли X NaN (Not a Number - не число).
math.modf(X) # возвращает дробную и целую часть числа X. Оба числа имеют тот же знак, что и X.
math.trunc(X) # возвращает целое число отвекая все, после запятой
math.exp(X) # возведение числа e в степень x
math.expm1(X) # eX - 1. При X → 0 точнее, чем math.exp(X)-1.
math.log(X, [base]) # логарифм X по основанию base. Если base не указан, вычисляется натуральный логарифм.
math.log1p(X) # натуральный логарифм (1 + X). При X → 0 точнее, чем math.log(1+X).
math.log10(X) # логарифм X по основанию 10.
math.log2(X) # логарифм X по основанию 2.
math.pow(X, Y) # x в степени y
math.sqrt(X) # квадратный корень из X.
math.acos(X) # арккосинус X. В радианах.
math.asin(X) # арксинус X. В радианах.
math.atan(X) # арктангенс X. В радианах.
math.atan2(Y, X) # арктангенс Y/X. В радианах. С учетом четверти, в которой находится точка (X, Y).
math.cos(X) # косинус X (X указывается в радианах).
math.sin(X) # синус X (X указывается в радианах).
math.tan(X) # тангенс X (X указывается в радианах).
math.hypot(X, Y) # вычисляет гипотенузу треугольника с катетами X и Y (math.sqrt(x * x + y * y)).
math.degrees(X) # конвертирует радианы в градусы.
math.radians(X) # конвертирует градусы в радианы.
math.cosh(X) # вычисляет гиперболический косинус.
math.sinh(X) # вычисляет гиперболический синус.
math.tanh(X) # вычисляет гиперболический тангенс.
math.acosh(X) # вычисляет обратный гиперболический косинус.
math.asinh(X) # вычисляет обратный гиперболический синус.
math.atanh(X) # вычисляет обратный гиперболический тангенс.
math.erf(X) # функция ошибок.
math.erfc(X) # дополнительная функция ошибок (1 - math.erf(X)).
math.gamma(X) # гамма-функция X.
math.lgamma(X) # натуральный логарифм гамма-функции X.
math.pi # pi = 3.141592653589793
math.e # e = 2.718281828459045

 

Как я сказал выше, есть еще и библиотека cmath для работы с вещественными числами. Для тех, кто пришел в Python именно для работы с математическими формулами, советую подробней изучить примеры использования библиотек math и cmath.