5-й час. Оновные типы данных: числовые

 

5-й час

Основные типы данных; числовые

  Изучая материал предыдущих четырех глав, мы подготовили почву для дальнейшего изучения Python — познакомились с базовыми концепциями объектно-ориентированного программирования и узнали о переменных. Но что мы знаем о том, что может храниться в этих переменных? Вы, вероятно, уже поняли, что переменные могут содержать самую различную полезную информацию, включая значения дат и времени, строки символов и даже целые функции. Но при этом нужно следовать определённым правилам сохранения данных и их интерпретации в Python. Чтобы разобраться в этих правилах, следует иметь представление о типах данных, поддерживаемых в Python. Этой теме как раз и посвящены настоящая и следующая главы. Здесь мы обсудим типы данных, представляющих числовые значения:

  • целое (integer);
  • длинное целое (long integer);
  • число с плавающей запятой (floating point);
  • комплексное число (complex).

Типы данных

  Для компьютера наступают трудные времена, когда он не может понять, что именно подразумевал программист в своей программе под той или иной переменной. Компьютеру необходимо чётко и ясно знать, сколько места в памяти следует отвести для данной переменной и как обрабатывать её содержимое. Отнесение переменной к опредёленному типу данных является тем методом, с помощью которого в программе можно явно указать все эти характеристики. Типы данных — это категории, на которые можно подразделить единицы информации, обрабатываемые программой. Типы данных в Python можно объединить в следующие категории более высокого порядка: числовые данные, последовательности, функции и типы, определяемые пользователем. Типы, определяемые пользователем, будут рассмотрены в части III этой книги. Числовые типы рассматриваются в этой главе, а остальные — в следующей.

  Типы данных в Python (как и в большинстве других языков программирования) делятся на две общие категории ещё более высокого порядка: основные (или базовые) и пользовательские (определяемые пользователем). Ко второй категории относятся объекты, с которыми, как уже говорилось, мы познакомимся ближе несколько позже. Объекты — это важнейшая составная часть объектно-ориентированного программирования, хотя различия между объектами и основными типами данных не всегда очевидны, особенно в случае применения функций. Кроме того, не все объекты определяются пользователем.

  В этой и следующей главах мы будем оперировать только с основными типами данных, к которым относятся числовой, последовательность и словарь. Функции будут рассмотрены в главе 7, остальные пользовательские типы, или объекты, освещаются в части II. А сейчас займёмся числовыми типами данных.

Числовые типы

  Компьютеры не наделены собственным интеллектом, поэтому программистам в большинстве языков программирования необходимо явно указывать, к какой разновидности чисел относится то или иное значение. Более того, компилируемым языкам эту информацию надо сообщать заранее, т.е. тип переменной должен быть объявлен до инициализации переменной. (Инициализация — это присвоение переменной первого значения.) Попытка присвоить переменной значение, не соответствующее объявленному для неё типу, закончится ошибкой в работе компилятора (чем он Вас непременно "порадует"). Например, предположим, что в С Вы объявляете переменную следующим образом:

int n;

  Эта строка подразумевает, что переменная n будет содержать положительные или отрицательные целые числа. Предположим, что где-то в коде своей программы Вы попробуете выполнить такое присвоение: n=3.14159;

  Компилятор языка С выразит Вам своё недовольство сообщением об ошибке и не позволит выполнить эту операцию. В отличие от С, Python с готовностью позволит Вам на ходу изменить тип переменной, причём без единой жалобы. Это объясняется способностью Python динамически определять типы переменных, в то время как в С переменные являются статичными. Другими словами, после объявления в С типа переменной компилятор строго следит за соответствием присваиваемых значений этому типу и не позволяет менять тип во время выполнения программы. В Python же тип переменной определяется в момент присвоения ей значения, поэтому тип переменной можно изменять столько, сколько вашей душе будет угодно. Профессиональный программист скажет, что такое свойство языка относится скорее к его недостаткам, чем к достоинствам. Очень трудно разобраться в коде, если одна и та же переменная в одном блоке содержит дату, а во втором — текст. Python предоставляет программистам множество возможностей, но старайтесь использовать эти возможности на пользу, а не во вред своей программе.

  *Прим. В. Шипкова: последний совет, по существу, довольно полезен. Мало того, что результат может оказаться ошибочным в плане точности вычислений, ещё и сами по себе преобразования из одного типа в другой это довольно затратная операция для процессора. Не стоит об этом забывать.

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

  Работа Python базируется на предположении, что программист знает, что делает. Статичность типов переменных в других языках — это результат реализации противоположной концепции, заключающейся в том, что программист нуждается в защите непосредственно от самого себя. Динамическое определение типов, если им не злоупотреблять, позволит существенно сократить и упростить код программы. Например, предположим, что Вы считываете строки символов, вводимые пользователем. Вы хотите преобразовать эти строковые данные в числа и использовать их в качестве входных данных своей программы. Если пользователю разрешается вводить целые числа, длинные целые и числа с плавающей запятой, то на обычном языке программирования Вам пришлось бы для этого предусмотреть по крайней мере три переменные трёх разных типов. А в Python Вам хватит всего лишь одной переменной, которая может содержать любое значение из трёх допустимых типов. И это становится возможным благодаря динамическому определению типов данных в Python.

  Мы начнём подробное обсуждение темы с уже знакомого Вам типа — целые числа.

Целые числа

  Тип целые числа (integer), как следует из его названия, представляет собой весь числовой ряд положительных и отрицательных целых чисел, а также нуль. Как и в других языках программирования, смысл использования данного типа данных состоит в экономии памяти, так как для сохранения целочисленного значения требуется меньше места, чем для значений других числовых типов. Большинство языков, включая Python, реализуют целые числа в виде 32-битовых значений, что ограничивает диапазон допустимых целочисленных значений пределами от -maxint до +maxint. Чтобы оценить допустимый диапазон значений на Вашем компьютере, запустите Python в режиме командной строки или воспользуйтесь редактором IDLE, импортируйте модуль sys и попробуйте выполнить ряд операций с числами maxint, как показано в листинге 5.1. На моём компьютере с Linux получились следующие значения (строки, вводимые пользователем, выделены полужирным шрифтом).

Листинг 5.1. Операции с maxint

Python 1.5.2 (10, Apr 13 1999, 10:51:12)

[MSC 32 bit (Intel)] on Win32

Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam

>>> from sys import *

>>> maxint

2147483647

>>> -maxint

-2147483647

>>> maxint + 1

Traceback (innermost last):

File "<pyshell#3>", line 1, in ?

maxint + 1

OvertlowError:

integer addition

>>>

  В некоторых системах целые числа представляются 64-битовыми значениями, а в системах Cray, насколько я знаю, для целых чисел отводится 128 бит. Тем не менее сообщение об ошибке OverflowError, которое Вы видите в приведенном выше примере, все равно появилось бы. Просто диапазон чисел, лежащих между значениями -maxint и +maxint, был бы намного больше. Я никогда не работал на столь мощных машинах, но с помощью другого типа данных Python — long integer (длинное целое) — можно оценить диапазоны целых чисел у таких машин. В листинге 5.2 приведён код программы, который необходимо ввести, сохранить в файле inttest.py и запустить с помощью Python. Кстати, что касается всех листингов кода, представленных в этой книге, то вместо того чтобы набирать их вручную, можно просто выгрузить их со страницы этой книги в Internet.

from sys import *

z = long ( maxint )

print "32-bit machine:"

print "maxint:",z,"-maxint:",-z,"(2**31L)-1:",(2**31L)-1

print "-----------------------------------------"

у = (2 ** 63L) - 1

print "64-bit machine:"

print "maxint:", y, "-maxint:", -y

print "--------------------------------------"

z = (2 ** 127L) - 1

print "128-bit machine:"

print "maxint:", z, "-maxint:", -z

На рис. 5.1 показан результат выполнения программы inttest.py.

  Обратите внимание, что на 32-разрядной машине самым большим целым числом, которое можно использовать, является значение (2**31L)-1. Это объясняется тем, что один бит используется для указания знака числа — положительного или отрицательного. В большинстве систем он называется старшим двоичным битом, или просто знаковым битом. Причина того, что Вы не можете использовать число, которое точно равно значению 2**31L (т.е. 21474836^8), довольно сложна и запутанна, чтобы объяснять её в данный момент. Она связана со способом представления чисел в двоичной системе.

  *Прим. В. Шипкова: я не считаю, что это столь уж сложно и непонятно. Поэтому объясняю. Нумерация ячеек памяти в компьютерах начинается с 0. Т. е. 1-ая ячейка памяти имеет адрес 0, 2-ая - 1 и т. д. Таким образом, как адресация, так и численное значение ячеек памяти будут иметь численный предел меньший на еденицу, чем можно было ожидать. Почему так? Да потому что, когда на шину адреса выставляются нули - это тоже число, и оно тоже должно что-то адресовать. Именно по этому, число ноль, частенько относят к положительным. ИМХО, это глюк разработчиков - по моему, когда на шину адресов выставляется ноль, это должно быть эквивалентно высокоимпедансному состоянию. Это когда микросхемы принудительно отключаются от шин. Сразу оговорюсь, при текущих схемах адресации пришлось бы пожертвовать нулевым байтом, т. к. он бы стал недоступен. С другой стороны, если хорошо подумать, то по предложенному мной варианту схема адресации была бы вряд ли проще (а на сколько сложней - надо полагать, уж посложней). Вот и мучаются программисты с системщиками забывая про эту "мелочь".

  Заинтересованным читателям рекомендую обратиться к разделу "Примеры и упражнения" этой главы, где помещены ссылки на дополнительные материалы. В их числе Вы найдёте серверы, посвященные исследованиям позиционных числовых систем, где параллельно освещаются и вопросы компьютерного представления чисел. Другие компьютерные языки позволяют хранить целые числа без знака, и такие числа, что очевидно, называются беззнаковыми (unsigned). Беззнаковые числа позволяют использовать все 32 бита, но только для представления положительных целых чисел.

Рис. 5.1. Результат выполнения программы inttest.py

  Аналогично, для 64-разрядной машины самым большим целым числом, которое допускается использовать, является значение (2 ** 63) - 1, а для 128-разрядной машины оно составляет (2 ** 127) - 1. В своей работе Вы, как правило, не будете достигать граничного значения maxint даже на 32-разрядных машинах. Максимальные значения целых чисел в 64- и 128-разрядном представлениях — это очень большие числа, которые могут понадобиться только для космических исследований или подсчетов числа молекул.

  Но если проблема с максимально (минимально) допустимыми значениями у Вас всё же возникнет, не отчаивайтесь. Длинные целые числа — вот способ, позволяющий обойти эти ограничения в Python, и мы обсудим их в следующем разделе.

Длинные целые числа

  Длинные целые числа типа long integer, которые иногда встречаются также под названиями longs или bigints, присутствовали в Python с самого начала. По существу, они ведут себя точно так же, как и обычные целые числа, но только не ограничены никакими пределами. Преобразование целых чисел в длинные целые числа и наоборот, к сожалению, не является достаточно прозрачной процедурой для программистов. Но есть надежда, что Гуидо устранит эти различия в будущих версиях Python. Впрочем, можно попробовать самостоятельно составить алгоритм, который будет автоматически выполнять эти преобразования, если Вам это потребуется.

  Что подразумевается под словами не ограниченные никакими пределами? В действительности это совсем не означает, что Вы можете использовать числа, уходящие в бесконечность. Имеется в виду только то, что обычные ограничения существенно расширяются. К чему это сводится на практике? К тому, что размер любого заданного длинного целого числа подчиняется только фактическим ограничениям, вытекающим из характеристик вашей машины. Например, Вы не можете использовать в своей программе такое число, для хранения которого потребуется больший объём памяти, чем её имеется фактически. Так, на моей домашней машине с системой Server Windows NT 4.0 установлено 256 Мбайт оперативной памяти. В идеале, если пренебречь обязательным расходованием памяти на функционирование операционной системы и самого интерпретатора Python, а также ряда обязательных утилит, самое большое длинное целое число, которое я мог бы теоретически использовать, должно уместиться в эти 256 Мбайт. В результате получилось бы число длиной что-то около 2`013`265`920 цифр. Это довольно приличное значение, но, тем не менее, конечное. Во внутреннем компьютерном представлении длинные целые хранятся как 16-рязрядные числа с максимальным значением 32 768. Поскольку 32 768 — это 2 в 15-й степени, становится очевидным, что 16-й разряд используется для чего-то ещё. Этот 16-й бит применяется для реализации "флага переполнения" (т.е. выхода за пределы), который используется для организации операций по переносу, заимствованию и т.п., что во многом напоминает то, как Вы поступаете, когда решаете расчетные задачи на бумаге. Чтобы лучше уяснить то, как устроены большие целые числа, попробуйте выполнить упражнения, приведенные в конце этой главы.

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

  С другой стороны, длинные целые числа просто необходимы для выполнения некоторых вычислений. Предположим, что Вам нужно преобразовать расстояние в световых годах в километры. С помощью Python это вычисление выполняется очень просто. Вам достаточно только знать, что скорость света (с) приблизительно равна 300`000 км/с. (Более точно значение, а также принципы расчета скорости света представлены на Web-странице по адресу http://ww.ph.uniraelb.edu.au/~nibailes/P140/lecture22/index.htm.) В листинге 5.3 приведена простая процедура определения длины космического светового года в километрах.

def c(p):

  spy = 60*60*24*365.2422

  n = long(spy)*long(p)

  return n

 

if __name__ == "__main__":

  n = c(300000)

  print n

  Хотя Вы ещё не знакомы с функциями, речь о которых пойдет только в следующей главе, я позволил себе забежать немного вперед и реализовал эту процедуру как вызов функции, в которую в качестве аргумента передаётся скорость света в вакууме. Если Вас не удовлетворяет точность вычислений и Вы захотите использовать более точное значение скорости света, достаточно просто изменить аргумент функции с() в строке 6.

Число 365,2422 в листинге 5.3 — это приблизительная длина года, выраженная в днях. Для расчётов дат по григорианскому календарю используется значение длины года 365,2425 дней. (В юлианском календаре использовалось менее точное приближение — 365,25 дней.) Тем не менее, к вашему сведению, астрономы, оперирующие световыми годами, используют в расчётах юлианский год, поскольку в действительности на расстояние, пробегаемое световой волной за год, влияет так много факторов, что большая точность вычислений будет статистически недостоверной. Астроном Дункан Стил (Duncan Steel) написал короткую заметку, в которой излагает несколько серьезных доводов, обосновывающих предпочтительность использования в вычислениях юлианской длины года. С этой статьей можно познакомиться на Web-странице по адресу http://www.pauahtun.org/TYPython/steel.html.

  Запустив на выполнение короткую программу с.ру, получим следующий результат: 9467077800000L

  Это, действительно, более 9х1012 км. Так нам говорили ещё в школе, хотя это расстояние трудно себе представить. Использование более точного значения скорости света в вакууме позволит повысить точность вычисления, но порядок и невообразимость конечного результата останутся теми же.

Числа с плавающей запятой

  В предыдущих главах мы уже встречались с числами с плавающей записей и с экспоненциальным представлением чисел. Надеюсь, Вы уже достаточно чётко представляете, о чем идёт речь. Числа с плавающей запятой (floating point) в Python являются аналогом типа double (числа с двойной точностью) в языке С. Двойная точность подразумевает выделение для их хранения 64 бит памяти. Часть этих битов выполняет служебные функции, поэтому фактически для данного типа самым большим и самым маленьким допустимыми значениями являются (приблизительно) 1.79769е+308 и 2.22507е-308 соответственно, по крайней мере на большинстве компьютеров. Плохо то, что Python не даёт вразумительного сообщения об ошибке в случае выхода значения с плавающей запятой за допустимые пределы. Вместо этого получаются довольно странные результаты. Посмотрите, что получится, если назначить переменной максимальное значение числа с плавающей запятой, а именно 1.79769е+308, а затем удвоить его. На своей машине с NT я получил следующий результат: 1. * INF. К счастью, существуют способы заставить Python сообщать Вам о возникновении ошибок подобного рода. Мы рассмотрим их в последующих главах.

  *Прим. В. Шипкова: я не поленился проверить, как обстоят с этим дела в версии 2.4. Что же я получил?1.#INF

Так что, поосторожней с этим делом.

Я думаю, это не связано конкретно с Питоном. Скорей всего - это результат работы сопроцессора.

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

  Если Вас интересуют характеристики собственного компьютера, загрузите из Internet файл http://www.pauahtun.org/TYPython/machar.zip. Это программа на языке С, которая после запуска на выполнение сообщает максимальные и минимальные предельные значения чисел с плавающей запятой. Для систем Linux и DOS программа доступна как исходный код программы, так и выполняемый файл. Для других систем программу нужно скомпилировать самостоятельно.

Комплексные числа

  Комплексные числа, как и длинные целые, были и остаются составной частью Python. Не так уж много найдется языков, которые обеспечивают встроенную поддержку использования комплексных чисел. ещё один язык, который может похвастать этой особенностью, — это FORTRAN. Но данное свойство принесет ощутимую помощь только в том случае, если Вы знаете, что представляют собой комплексные числа.

  Комплексные числа успешно прижились в электронике, где благодаря их применению с восхитительной простотой описывается поведение сложных электроцепей. Они также весьма эффективны в описании механики небесных тел, в частности для решения систем уравнений, которые помогают астрономам рассчитывать орбиты планет, спутников и астероидов. А не так давно они нашли широкое применение в компьютерной графике, во многом благодаря их популяризации (если допустимо употребить здесь это слово) Беноитом Мандельбротом (Benoit Mandelbrot), сотрудником корпорации IBM, который открыл математическое множество, названное теперь его именем. В последующих главах Вы увидите, как можно использовать комплексные числа для рисования наборов Мандельброта (Mandelbrot set).

  Чтобы уяснить, что представляют собой комплексные числа, вспомните материал предыдущих глав, в которых целые числа мы рассматривали в виде значений, расположенных на одной линии с нулем в центре, протяжённой бесконечно в обоих направлениях, — отрицательном и положительном. (Хотя в действительности в компьютере они не уходят в бесконечность, а ограничены минимальным и максимальным допустимыми значениями.) Вот пример целых чисел: ...-3,-2,-1, 0, 1, 2, 3... . Длинные целые числа в Python находятся на той же самой числовой оси, только их пределы дальше отдалены влево и вправо. На этой же числовой оси располагаются и числа с плавающей запятой, только они заполняют ось сплошным рядом. Если каждый отрезок числовой оси, расположенный между двумя смежными целыми числами, разбить на бесконечное множество точек, то это и будут числа с плавающей запятой. Совокупность целых чисел и чисел с плавающей запятой называется вещественные числа.

  Когда мы говорим о числах и числовой оси, то фактически подразумеваем элементы четырех числовых систем.

  1. Натуральные, или счётные, числа: 1, 2, 3 и т.д.
  2. Целые числа:-3,-2,-1, 0,1, 2, 3 и т.д.
  3. Рациональные числа: 3/4, 5/8, 1/10 и т.д.
  4. Вещественные числа: 3,14159, 1,001 и т.д., включая иррациональные числа.

  Возможно, Вы уже слышали об иррациональных числах, среди которых число "пи" является самым известным (отношение диаметра к радиусу окружности). Эти числа могут быть выражены только как отношение двух других чисел (в виде дроби а/Ь). Если попытаться определить их фактическое значение, то мало того, что они не только не дают никакого конечного значения, типа 1,5/0,5 = 3,0, но не получится даже периодической десятичной дроби, такой как 10,0/3,0= 3,33333333333333... . Вместо этого получается бесконечная дробь без какого бы то ни было намёка на подобие закономерности. В научно-фантастическом рассказе "Контакт" писателя Карла Сагана (Carl Sagan — "Contacf") описывается сообщение, скрытое в числе "пи" в районе десятичных разрядов, расположенных где-то за сотней миллиардов знаков после запятой. Если бы это было правдой, мы действительно имели бы послание богов, а не только каких-то там инопланетян. Но любое сообщение — это закономерность, а чередование знаков в числе я — это случайность. Так что поиск подобных посланий противоречит фактам современной математики.

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

  Существует, однако, ещё одна категория чисел, которые вообще невозможно расположить на числовой прямой. Это — мнимые числа. На ранних этапах развития математической науки даже отрицательные числа рассматривались как бессмысленные. Имеются в виду математические представления древних цивилизаций, таких как индейцы Майя. Чтобы представить себе отрицательные числа, нужно было обладать достаточным уровнем абстрактного мышления. Позже, когда появились первые намёки на то, что теперь называется мнимыми числами, математики по инерции были склонны скорее игнорировать собственные же открытия.

  Классический пример мнимого числа — квадратный корень из -1. Квадрат некоторого числа по определению является результатом умножения этого числа самого на себя. Тогда само это число называется корнем. Например, 5 является квадратным корнем числа 25. ещё со школы мы помним, что при умножении двух чисел с одинаковым знаком, даже если этот знак отрицательный, результат всегда будет положительным. Следовательно, знак подкоренного числа обязательно должен был положительным. Невозможно извлечь квадратный корень из отрицательного числа. Но тут возникает противоречие. Поскольку отрицательные числа все же существуют и их можно возводить в квадрат, то должна быть возможность и извлекать из них корень. Перед нами возникает та же проблема отрицательных значений, которая стояла перед древними математиками. Очевидно, что они должны существовать, но их невозможно себе представить.

  Чтобы использовать мнимые числа, их следует представить в формате комплексных чисел. Современные математики помещают мнимые числа на оси, перпендикулярной числовой оси вещественных чисел. Тогда комплексные числа представляются в виде совокупности вещественного и мнимого компонентов. Комплексные числа подчиняются правилам сложения, вычитания и умножения. Фактически любое действие, которое может быть выполнено над вещественными числами, может быть также выполнено и над комплексными числами. Следуя этим правилам, мы можем вычислить квадратный корень из -1. Вещественная часть комплексного числа пишется просто как она есть, а мнимая составляющая представлена числом, за которым следует суффикс — буква i или j Поскольку в Python используется буква j, я также буду применять её в этой книге. Квадратный корень числа -1 записывается в виде (0, 1j). Умножение комплексных чисел выполняется в соответствии со следующим правилом: (a,b)(c,d) = (ac-bd, ad+bc)

Выполним его для числа (0, 1j) и получим следующий результат:

(0, 1j)(0, 1j)

{0*0) - (1*1), (0*1) + (1*0)

(0-1), (0+0)

(-1, 0j)

  Как видим, при отображении результата на числовой плоскости мнимый элемент (0, 1j) пропадает, в результате чего получаем вещественное число -1.

  Подобные действия просто выполнять в Python, потому что в него встроена поддержка комплексных чисел. Все, что необходимо сделать в Python, — это определить число как комплексное. В этом нет никаких проблем. Следующий пример демонстрирует, как сообщить Python, что переменная а является комплексным числом:

а=0+1j

  Возвести в квадрат это комплексное число также просто: s=а*а

  Python зорко отследит комплексный характер переменной а и автоматически сделает комплексным результат возведения этого числа в квадрат (переменная s). Выполнение обычных математических операторов над комплексными числами будет давать правильный результат, в чём можно убедиться, если перемножить два комплексных числа. Фактически любое действие, которое можно выполнять над числами с плавающей запятой, может быть применено для комплексных чисел. Правда, для этого нужно импортировать в программу модуль математических функций для обработки комплексных чисел. Вспомните, что в предыдущих главах для получения доступа к математическим функциям, таким как sqrt(), приходилось импортировать модуль math: from math import *

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

i = sqrt (1.0)

  Если мы попытаемся выполнить ту же операцию с комплексными числами, то Python выразит своё недовольство, как показано на рис. 5.2.

Рис. 5.2. Функции модуля math

  Чтобы использовать математические функции для обработки комплексных чисел, следует импортировать специальный модуль cmath. Синтаксис импортирования модуля остаётся тот же: from cmath import *

  Повторим опять нашу операцию с комплексным числом. В этот раз Python не покажет сообщения об ошибке, а возвратит правильный результат (рис. 5.3).

Рис. 5.3. Модуль математических функций для комплексных чисел

  Но может возникнуть другая проблема. Внимательно рассмотрите введенные строки на рис. 5.3. Все функции в модулях math и cmath имеют одинаковые имена. Если последним был импортирован модуль cmath, то все функции чисел с плавающей запятой заменяются их эквивалентами для комплексных чисел. В результате все числа с плавающей запятой будут обрабатываться как комплексные. Но что делать, если необходимо использовать функции из обоих модулей? Этот случай отчётливо подчеркивает одну из опасностей импортирования модулей выражением from module import *. Рано или поздно Вы обязательно потеряете что-нибудь из того, что Вам необходимо! Решение этой проблемы заключается в том, чтобы использовать идентификаторы, явно указывающие модуль-источник функции. Пример использования идентификаторов показан на рис. 5.4.

Рис. 5.4. Использование идентификаторов модулей функций для комплексных чисел и для чисел с плавающей запятой

  Символ (.) является оператором прямого обращения. Он используется для указания модуля, из которого необходимо взять данную функцию. Например, на рис. 5.4 мы попеременно обращались к одноименным функциям sqrt () двух модулей — math и cmath. Оператор прямого обращения (.) используется также для получения доступа к членам классов, о чем мы узнаем в разделе, посвящённом объектам.

Резюме

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

Практикум

Вопросы и ответы

Где в реальном мире используются комплексные числа?

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

  Я выполнил на своём компьютер программу machar.exe и определил, что для представления чисел с плавающей запятой используется только 53 бита из 64. Чем это можно объяснить?

  В действительности 53 бита используются только для мантиссы, т.е. дробной части, а ещё 11 битов используются для показателя степени. В сумме для представления значения с плавающей запятой используется 64 бита.

Контрольные вопросы

  1. Из каких двух компонентов состоят комплексные числа?

    а) Вещественного и не вещественного чисел.

    б) Мнимого и кошмарного.

    в) Мнимого и вещественного.

    г) Ужасного и прекрасного.

  2. Какие пять числовых систем упоминались в этой главе?

    а) Натуральные, искусственные, мнимые, рациональные и иррациональные.

    б) Натуральные, целые, рациональные, вещественные и комплексные.

    в) Ордовикские, силурийские, девонские, юрские и триасовые.

    г) А, В, С, D и Е.

  3. Что произойдет, если импортировать два модуля, в которых имеются одноимённые функции?

    а) В случае использования идентификаторов не произойдет ничего страшного.

    б) Если использовать инструкцию import *, функции второго модуля заместят одноимённые функции первого.

    в) Одноименные функции обоих модулей окажутся недоступными.

    г) Окажутся недоступными все функции обоих модулей.

Ответы

  1. в. Комплексные числа состоят из мнимой и вещественной составляющих.

  2. б. Пять числовых систем: натуральные, целые, рациональные, вещественные и комплексные числа.

  3. а и б. Если импорт модулей выполняется с помощью ключевого слова import без звездочки, то перед именами функций следует указывать имена модулей, что одновременно предотвратит возникновение конфликтов имён. Если импортировать модули с помощью инструкции import *, то функции первого модуля будут замещены одноименными функциями второго модуля. Идентификаторы в этом случае не исправят положения.

Примеры и задания

  Для ознакомления с вводным материалом по мнимым, комплексным, рациональным и иррациональным числам, а также по другим близким темам загляните на Web-узел по адресу http://www.math.toronto.edu/mathnet/answers/imaginary.html.

  Интересные сведения о календаре индейцев Майя представлены на Web-странице по адресу http://www.foretec.com/Python/workshops/1998-ll/proceedings.html. Здесь же Вы узнаете о том, как представляли себе отрицательные числа мудрецы Майя.

  Просмотрите ещё раз внимательно главу 3, в частности те разделы, где речь идёт о представлении чисел с плавающей запятой в Python и о проблемах с точностью арифметических действий с этими значениями.