Числа в Python
В этой статье вы узнаете, какие типы чисел есть в Python, научитесь приводить один тип к другому и производить с числами математические операции.
Какие числа поддерживаются
Python поддерживает комплексные (complex), целые числа (integer) и числа с плавающей точкой (float).
Целые числа и числа с плавающей точкой отличаются наличием или отсутствием десятичного разделителя. Например, 5
— целое число, а 5.0
— число с плавающей точкой.
Целые числа могут быть любой длины. Точность чисел с плавающей точкой обеспечивается только до 15 знака, на 16 могут возникать неточности.
Комплексные числа записываются следующим образом: x + yj
. Здесь x
— действительная часть, а y
— мнимая.
Чтобы узнать, к какому типу относится переменная, используйте функцию type()
. Если вы хотите узнать, принадлежит ли переменная определенному классу, используйте isinstance()
.
a = 5
print(type(a))
print(type(5.0))
c = 5 + 3j
print(c + 3)
print(isinstance(c, complex))
Вывод:
<class 'int'>
<class 'float'>
(8+3j)
True
Системы счисления
Числа, с которыми мы ежедневно сталкиваемся, представлены в десятичной системе счисления. Но программисты чащего всего работают с двоичной (основанием 2), шестнадцатеричной (основание 16) и восьмеричной (основание 8) системами счисления.
Эти числа в Python могут быть представлены с помощью соответствующего префикса. Они записаны в таблице ниже.
Система счисления |
Префикс |
Двоичная |
|
Восьмеричная |
|
Шестнадцатеричная |
|
Вот как это выглядит:
# выведет 107
print(0b1101011)
# выведет 253, т. к. 251 + 2) = 253
print(0xFB + 0b10)
# выведет 13
print(0o15)
Вывод:
107
253
13
Приведение типов
В Python один тип числа можно конвертировать в другой. Это называется приведением типов.
Операции вроде сложения или вычитания неявно, то есть автоматически, приводят целочисленный тип к числу с плавающей точкой, если один из операндов является числом с плавающей точкой.
>>> 1 + 2.0
3.0
Как видите, при сложении 1 (это целое число) приводится к 1.0 (это число с плавающей точкой). Результат тоже будет числом с плавающей точкой.
Чтобы выполнить явное преобразование, вы можете использовать встроенные функции int()
, float()
, complex()
. С помощью них к численным типам можно приводить даже строки.
>>> int(2.3)
2
>>> int(-2.8)
-2
>>> float(5)
5.0
>>> complex('3+5j')
(3+5j)
При приведении числа с плавающей точкой к целому десятичная часть удаляется. Говорят, что она «обрезается».
Модуль decimal
Встроенный класс float порой может выдавать удивительные результаты. Все мы знаем, что 1.1 + 2.2 = 3.3, но Python, кажется, так не думает.
Введите в IDLE на своем компьютере такую строку:
>>> (1.1 + 2.2) == 3.3
False
Почему False
? Что не так?
Оказывается, что числа с плавающей точкой в памяти компьютера реализованы с помощью двоичных дробей — компьютер понимает только их (0 и 1). Именно поэтому большинство десятичных дробей невозможно со всей точностью хранить в памяти компьютера.
Приведем пример. Мы не можем представить дробь ⅓ в виде десятичного числа. ⅓ = 0.33333333… период — бесконечный. Поэтому хранить можно лишь приблизительное значение этого числа.
То есть десятичная дробь 0.1 — это бесконечная двоичная дробь 0.000110011001100110011… и компьютер может хранить в памяти только конечное число цифр после точки. Это лишь приближенное к 0.1 значение, но не равное ему. Следовательно, это аппаратные ограничения, а не ошибка Python.
>>> 1.1 + 2.2
3.3000000000000003
Для решения этой проблемы мы можем использовать модуль decimal, встроенный в Python. Тип float имеет точность до 15 знаков, а decimal — настраиваемую пользователем.
Разница налицо:
import decimal
print(0.1)
print(decimal.Decimal(0.1))
Вывод:
0.1
0.1000000000000000055511151231257827021181583404541015625
Этот модуль полезен, когда нам нужно вычислять десятичные дроби так же, как в школе.
Положение точки тоже сохраняется. Мы знаем, что 25.50 кг точнее, чем 25.5 кг, так как у этой дроби два числа после точки.
from decimal import Decimal as D
print(D('1.1') + D('2.2'))
print(D('1.2') * D('2.50'))
Вывод:
3.3
3.000
Обратите внимание на нули в вышеприведенном примере.
Вы можете подумать: почему бы тогда не использовать модуль decimal вместо float постоянно? Справедливый вопрос.
Дело в эффективности. Операции с float происходят гораздо быстрее, чем с decimal.
Когда стоит использовать decimal вместо float?
- При создании приложения для работы с финансами. Здесь нужна точность.
- Когда нужно держать уровень точности на определенном уровне.
- Когда нужно реализовать дробь с определенным числом цифр после точки.
Модуль fractions
В Python есть модуль fractions, он производить операции с дробными числами.
У дробей есть числитель и знаменатель — это целые числа. Также этот модуль позволяет производить операции с рациональными числами.
Создать fraction-объект можно разными способами. Давайте их разберем:
import fractions
print(fractions.Fraction(1.5))
print(fractions.Fraction(5))
print(fractions.Fraction(1,3))
Вывод:
3/2
5
1/3
При создании fraction-объекта из float могут возникнуть неожиданные результаты. Происходит это, как говорилось выше, из-за несовершенного двоичного представления чисел с плавающей точкой.
К счастью, fraction позволяет создать экземпляр из строки. Настоятельно рекомендуем использовать именно этот способ, когда аргументом является десятичное число.
import fractions
# Число с плавающей точкой
# Вывод: 2476979795053773/2251799813685248
print(fractions.Fraction(1.1))
# Строка
# Вывод: 11/10
print(fractions.Fraction('1.1'))
Вывод:
2476979795053773/2251799813685248
11/10
Этот тип данных поддерживает все базовые математические операции.
from fractions import Fraction as F
# со всеми работает
print(F(1, 3) + F(1, 3))
print(1 / F(5, 6))
print(F(-3, 10) > 0)
print(F(-3, 10) < 0)
Вывод:
2/3
6/5
False
True
Модуль math и random
Для решения тригонометрических, логарифмических, вероятностных и статистических задач Python располагает встроенными модулями math и random.
import math
print(math.pi)
print(math.cos(math.pi))
print(math.exp(10))
print(math.log10(1000))
print(math.sinh(1))
print(math.factorial(6))
Вывод:
3.141592653589793
-1.0
22026.465794806718
3.0
1.1752011936438014
720
import random
print(random.randrange(10, 20))
x = ['а', 'б', 'в', 'г', 'д']
# Получаем случайный набор из х
print(random.choice(x))
# Перемешиваем x
random.shuffle(x)
# Выводим в консоль перемешанный список x
print(x)
# Выводим в консоль случайный элемент
print(random.random())
Примечание. Ваш вывод может отличать, поскольку функции модуля random выбирают элементы случайно.
Вывод:
13
а
['г', 'б', 'д', 'а', 'в']
0.038881285348306704