Книга: Как устроен Python. Гид для разработчиков, программистов и интересующихся
Назад: 7. Подробнее об объектах
Дальше: 9. Строки

8. Числа

В этой главе рассматриваются операции с числами в языке Python. В Python поддерживаются целые числа (такие, как −1, 5 или 2000) и числа с плавающей точкой (приближенное компьютерное представление таких чисел, как 0,333, 0,5 или −1000,234); они позволяют легко выполнять числовые операции. Изначально в Python предусмотрена поддержка операций сложения, вычитания, умножения, деления, возведения в степень, вычисления остатка и многих других операций!

В отличие от других языков, в Python существуют только объекты — это относится и к числам. Целые числа относятся к классу int:

>>> type(1)

<class 'int'>

Числа с плавающей точкой относятся к классу float:

>>> type(2.0)

<class 'float'>

Точность представления нецелых чисел ограничена. Пользователь должен сам определить, достаточно ли ее для его текущих вычислений. Во внутреннем представлении чисел с плавающей точкой Python использует двоичное представление (соответствующее стандарту IEEE 754 для чисел с плавающей точкой). У чисел с плавающей точкой существует определенный порог точности, поэтому возможна погрешность округления. Собственно, разработчик всегда должен ожидать, что вычисления выполняются с погрешностью округления. (Если вам потребуется более высокая точность, модуль decimal предоставляет более точную, хотя и более медленную реализацию.)

Рассмотрим точность представления на простом примере. Что происходит при выполнении простой на первый взгляд операции вычитания?

>>> print(1.01 - .99)

0.020000000000000018

СОВЕТ

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

8.1. Сложение

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

>>> 2 + 6

8

ПРИМЕЧАНИЕ

В этом примере результат не связывается с переменной. Для вывода результата простейшего вычисления на терминал этого может быть достаточно. Если результат вдруг понадобится вам позднее, интерпретатор Python сохраняет последний результат в переменной с именем _:

>>> 2 + 6

8

>>> result = _

>>> result

8

 

При сложении двух целых чисел будет получено целое число. Аналогичным образом можно сложить два числа с плавающей точкой:

>>> .4+.01

0.41000000000000003

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

А что произойдет при сложении целого числа с числом с плавающей точкой?

>>> 6 + .2

6.2

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

ПРИМЕЧАНИЕ

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

ПРИМЕЧАНИЕ

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

При использовании % со строкой в левой части (левый операнд) и любым объектом (включая числа) в правой части (правый операнд) Python выполняет операцию форматирования:

>>> print('num: %s' % 2)

num: 2

Если левый операнд является строкой, то при применении оператора умножения * Python выполняет повторение:

>>> 'Python!' * 2

'Python!Python!'

 

>>> '4' * 2

'44'

 

ПРИМЕЧАНИЕ

С классами int и float могут выполняться явные преобразования (несмотря на внешнее сходство с функциями, в действительности это классы):

>>> int(2.3)

2

 

>>> float(3)

3.0

 

8.2. Вычитание

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

>>> 2 - 6

-4

 

>>> .25 - 0.2

0.04999999999999999

 

>>> 6 - .2

5.8

8.3. Умножение

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

>>> 6 * 2

12

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

>>> .25 * 12.0

3.0

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

>>> 4 * .3

1.2

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

8.4. Деление

В Python (как и во многих языках) знак / обозначает деление:

>>> 12 / 4

3.0

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

>>> 3 / 4

0.75

Прежде в Python выполнялось целочисленное деление. Если вам нужен именно такой вариант поведения, используйте оператор //. Какое целое число использует Python? Результат округления в меньшую сторону:

>>> 3 // 4

0

8.5. Остаток

Оператор % вычисляет остаток от целочисленного деления. Например, с его помощью можно проверить число на четность (или узнать, были ли обработаны 1000 элементов списка):

# Остаток от деления 4 на 3

>>> 4 % 3

1

>>> 3 % 2 # нечетно, если результат равен 1

1

>>> 4 % 2 # четно, если результат равен 0

0

СОВЕТ

Будьте внимательны при использовании оператора % с отрицательными числами. Поведение оператора изменяется в зависимости от того, какой из операндов отрицателен. Понятно, что при отсчете в обратном направлении остаток должен повторяться с определенной периодичностью:

>>> 3 % 3

0

>>> 2 % 3

2

>>> 1 % 3

1

>>> 0 % 3

0

Какой результат должен быть получен при вычислении -1 % 3? Так как отсчет ведется в обратном направлении, результат снова должен быть равен 2:

>>> -1 % 3

2

Но если изменить знак делителя, происходит нечто странное:

>>> -1 % -3

-1

Python гарантирует, что знак результата совпадает со знаком делителя (или равен 0). Чтобы окончательно запутать вас, еще один пример:

>>> 1 % -3

-2

Мораль: пожалуй, вам не стоит вычислять остаток с отрицательным делителем — только если вы твердо уверены в том, что вам действительно нужно именно это.

8.6. Возведение в степень

Python также поддерживает оператор возведения в степень ** (две звездочки). Если вы хотите возвести 4 в квадрат (4 — основание, 2 — показатель степени), это делается так:

>>> 4 ** 2

16

Результаты операции возведения в степень обычно стремительно увеличиваются. Допустим, вы хотите возвести 10 в 100-ю степень:

>>> 10 ** 100

10000000000000000000000000000000000000

00000000000000000000000000000000000000

0000000000000000000000000

Для хранения целых чисел программам требуется определенный объем памяти. Так как целые числа обычно относительно невелики, Python оптимизирует затраты памяти, чтобы избежать ее непроизводительного расходования. Во внутренней реализации «системные» целые числа могут быть преобразованы в длинные целые для хранения больших чисел. Python 3 делает это за вас автоматически.

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

Точно так же Python старается оптимизировать память для хранения целых чисел, ориентируясь на небольшие размеры. Если целое число не помещается в малый блок памяти (мешок), Python преобразует его в большое целое. На самом деле это желательное поведение, потому что в некоторых средах ошибка переполнения приводит к аварийному завершению программы (или PacMan отказывается переходить на уровни выше 255, потому что счетчик уровня хранится в виде 8-разрядного числа).

ПРИМЕЧАНИЕ

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

>>> import operator

>>> operator.add(2, 4) # same as 2 + 4

6

 

8.7. Порядок операций

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

>>> 4 + 2 * 3

10

>>> (4 + 2) * 3

18

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

8.8. Другие операции

Справочный раздел REPL весьма полезен. В нем имеется тема NUMBERMETHODS, объясняющая, как работают все числовые операции.

8.9. Итоги

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

8.10. Упражнения

1. В эту неделю вы спали 6,2, 7, 8, 5, 6,5, 7,1 и 8,5 часа. Вычислите среднюю продолжительность сна в часах.

2. Делится ли число 297 без остатка на 3?

3. Чему равен результат возведения 2 в десятую степень?

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

«…високосным оставался год, номер которого кратен четырем, но исключение делалось для тех, которые были кратны 100. Такие годы были високосными только тогда, когда делились еще и на 400… Так, годы 1700, 1800 и 1900 не являются високосными, так как они кратны 100 и не кратны 400. Годы 1600 и 2000 — високосные».

Напишите код Python, который определяет, являются ли високосными годы 1800, 1900, 1903, 2000 и 2002.

Назад: 7. Подробнее об объектах
Дальше: 9. Строки