Математический анализ. 3е издание
Скачать 4.86 Mb.
|
156 Глава 5. Числа имеются гораздо лучшие способы представления информации, чем по следовательности битов. Длинные целые Теперь добавим немного экзотики и посмотрим на длинные целые в дей ствии. Когда целочисленный литерал завершается символом L (или l), интерпретатор создает длинное целое число. В Python длинные целые могут иметь произвольную величину. То есть такое число может со держать такое число цифр, на которое хватит памяти в компьютере: >>> 9999999999999999999999999999999999999L + 1 10000000000000000000000000000000000000L Символ L в конце литерала предписывает интерпретатору Python соз дать объект длинного целого числа, способный представлять число с произвольной точностью. В действительности, начиная с версии Py thon 2.2, даже символ L в конце литерала можно не указывать. Интер претатор автоматически преобразует обычное целое число в длинное целое, если его значение превысит величину, которая может быть представлена обычным целым числом (с технической точки зрения – когда число превысит величину, которую способно вместить 32бито вое целое число). То есть вам не требуется указывать символ L, так как Python автоматически выполнит необходимые преобразования, когда в этом возникнет потребность: >>> 9999999999999999999999999999999999999 + 1 10000000000000000000000000000000000000L Длинные целые – это достаточно удобный инструмент. Например, с их помощью можно представить национальный бюджет в копейках (если вам это интересно и в вашем компьютере имеется достаточный объем памяти). Именно по этой причине нам удалось в примерах из главы 3 вычислить такую большую степень числа 2: >>> 2L ** 200 1606938044258990275541962092341162602522202993782792835301376L >>> >>> 2 ** 200 1606938044258990275541962092341162602522202993782792835301376L Так как интерпретатору приходится производить дополнительные действия, чтобы обеспечить поддержку высокой точности, математи ческие операции с участием длинных целых чисел обычно выполня ются существенно медленнее, чем операции с обычными целыми чис лами (которые, как правило, выполняются непосредственно аппарат ными средствами). Однако, если важна высокая точность, то фактор низкой производительности уходит на задний план. Числа в действии 157 Комплексные числа Комплексные числа – это особый базовый тип данных в Python. Если вы знаете о существовании комплексных чисел, вы должны знать, ко гда они используются. В противном случае этот раздел можно пропус тить. Комплексные числа состоят из двух чисел с плавающей точкой, представляющих вещественную и мнимую части, и в тексте програм мы отличаются наличием суффикса J, или j, после мнимой части. Ес ли вещественная часть не равна нулю, комплексное число записывает ся как сумма двух частей, с помощью символа +. Например, комплекс ное число, вещественная часть которого равна 2, а мнимая часть 3, за писывается как 2 + 3j.Ниже приводятся примеры некоторых действий над комплексными числами: >>> 1j * 1J (1+0j) >>> 2 + 1j * 3 (2+3j) >>> (2 + 1j) * 3 (6+3j) Кроме того, комплексные числа позволяют обращаться к своим час тям, как к атрибутам, поддерживают все обычные математические опе рации и могут обрабатываться с помощью стандартного модуля cmath (версия модуля math, предназначенная для работы с комплексными числами). Комплексные числа обычно используются в инженерных программах. Поскольку это инструмент повышенной сложности, ищи те подробности в справочном руководстве к языку Python. Шестнадцатеричная и восьмеричная формы записи чисел Как уже говорилось ранее, целые числа в языке Python могут записы ваться в шестнадцатеричной (по основанию 16) и восьмеричной (по ос нованию 8) форме: • Восьмеричные литералы должны начинаться с символа 0, вслед за которым следует последовательность восьмеричных цифр 07, каж дая из которых представляет три бита. • Шестнадцатеричные литералы должны начинаться с комбинации символов 0x или 0X, вслед за которой следует последовательность шестнадцатеричных цифр 09 и AF (в верхнем или в нижнем реги стре), каждая из которых представляет четыре бита. Имейте в виду, что это всего лишь альтернативный синтаксис задания значений целочисленных объектов. Например, следующие восьмерич ные и шестнадцатеричные литералы создают обычные целые числа с за данными значениями: >>> 01, 010, 0100 # Восьмеричные литералы (1, 8, 64) 158 Глава 5. Числа >>> 0x01, 0x10, 0xFF # Шестнадцатеричные литералы (1, 16, 255) Здесь восьмеричное значение 0100 соответствует десятичному значе нию 64, а шестнадцатеричное 0xFF – десятичному 255. По умолчанию интерпретатор Python выводит числа в десятичной системе счисления (по основанию 10), но предоставляет встроенные функции, которые позволяют преобразовывать целые числа в последовательности вось меричных и шестнадцатеричных цифр: >>> oct(64), hex(64), hex(255) ('0100', '0x40', '0xff') Функция oct выводит целое число в восьмеричном представлении, а функция hex – в шестнадцатеричном. Кроме того, существует воз можность обратного преобразования – встроенная функция int, кото рая преобразует строку цифр в целое число. Во втором необязательном аргументе она может принимать основание системы счисления: >>> int('0100'), int('0100', 8), int('0x40', 16) (100, 64, 64) Функция eval, с которой мы встретимся далее в этой книге, интерпре тирует строку во входном аргументе, как программный код на языке Python. Поэтому она имеет похожий эффект (хотя обычно она работает заметно медленнее, потому что ей приходится компилировать и вы полнять строку как часть программы, а это предполагает, что вы долж ны иметь безграничное доверие к источнику запускаемой строки – дос таточно грамотный пользователь мог бы подсунуть вашей программе строку, которая при выполнении в функции eval удалит все файлы на вашем компьютере!): >>> eval('100'), eval('0100'), eval('0x40') (100, 64, 64) Наконец, целые числа могут быть преобразованы в восьмеричное и ше стнадцатеричное представления с помощью строки выражения форма тирования: >>> "%o %x %X" % (64, 64, 255) '100 40 FF' Строки форматирования будут рассматриваться в главе 7. Прежде чем двинуться дальше, считаю своим долгом предупредить вас: будьте осторожны при использовании ведущего нуля в языке Py thon, если вы не предполагаете использование восьмеричных литера лов. Интерпретатор Python будет воспринимать их как числа в восьме ричной системе счисления, что может не соответствовать вашим ожи даниям – число 010 всегда соответствует десятичному числу 8, а не де сятичному 10 (независимо от того, что вы имели в виду!). Числа в действии 159 Другие встроенные средства для работы с числами В дополнение к этим базовым типам объектов Python предоставляет встроенные функции и модули для работы с числами. Встроенные функ ции int и round, например, усекают и округляют числа с плавающей точ кой, соответственно. В следующем примере демонстрируется использо вание модуля math (который содержит реализацию множества функций из библиотеки math языка C) и нескольких встроенных функций: >>> import math >>> math.pi, math.e # Распространенные константы (3.1415926535897931, 2.7182818284590451) >>> math.sin(2 * math.pi / 180) # Синус, тангенс, косинус 0.034899496702500969 >>> math.sqrt(144), math.sqrt(2) # Квадратный корень (12.0, 1.4142135623730951) >>> abs( 42), 2**4, pow(2, 4) (42, 16, 16) >>> int(2.567), round(2.567), round(2.567, 2) # Усечение, округление (2, 3.0, 2.5699999999999998) Как уже указывалось ранее, если в последнем случае использовать ин струкцию print, мы получим результат (2, 3.0, 2.57). Обратите внимание, что встроенные модули, такие как math, необходи мо импортировать, а встроенные функции, такие как abs, доступны все гда, без выполнения операции импорта. Говоря другими словами, моду ли – это внешние компоненты, а встроенные функции постоянно распо лагаются в пространстве имен, которое используется интерпретатором Python по умолчанию для поиска имен, используемых программой. Это пространство имен соответствует модулю с именем __builtin__. В чет вертой части книги мы подробнее поговорим о разрешении имен, а по ка всякий раз, когда слышите слово «модуль», думайте: «импорт». Модуль random из стандартной библиотеки также необходимо импорти ровать. Этот модуль предоставляет возможность получения случай ных чисел с плавающей точкой в диапазоне от 0 до 1, случайных це лых чисел в заданном диапазоне, случайного выбора элементов после довательности и многое другое: >>> import random >>> random.random() 0.49741978338014803 >>> random.random() 0.49354866439625611 >>> random.randint(1, 10) 5 >>> random.randint(1, 10) 4 160 Глава 5. Числа >>> random.choice(['Life of Brian', 'Holy Grail', 'Meaning of Life']) 'Life of Brian' >>> random.choice(['Life of Brian', 'Holy Grail', 'Meaning of Life']) 'Holy Grail' Модуль random может использоваться, например, для перемешивания колоды карт в игре, случайного выбора изображения в программе де монстрации слайдов, в программах статистического моделирования и т. д. За дополнительной информацией обращайтесь к руководству по стандартной библиотеке языка Python. Другие числовые типы В этой главе мы рассматривали базовые числовые типы языка Python – целые числа, длинные целые, числа с плавающей точкой и комплекс ные числа. Их вполне достаточно для решения математических задач, с которыми придется столкнуться большинству программистов. Одна ко язык Python содержит несколько более экзотических числовых ти пов, которые заслуживают того, чтобы коротко познакомиться с ними. Числа с фиксированной точностью В версии Python 2.4 появился новый базовый числовой тип: числа с фиксированной точностью представления. Синтаксически такие числа создаются вызовом функции из импортируемого модуля и не имеют литерального представления. Функционально числа с фикси рованной точностью напоминают числа с плавающей точкой, с фикси рованным числом знаков после запятой, отсюда и название «числа с фиксированной точностью». Например, с помощью таких чисел мож но хранить значение, которое всегда будет иметь два знака после запя той. Кроме того, можно указать, как должны обрабатываться лишние десятичные цифры – усекаться или округляться. И хотя скорость ра боты с такими числами несколько ниже, чем с обычными числами с плавающей точкой, тем не менее тип чисел с фиксированной точно стью идеально подходит для представления величин, имеющих фик сированную точность, таких как денежные суммы, и для достижения лучшей точности представления. Точность при работе с обычными вещественными числами несколько ниже. Например, результат следующего выражения должен быть ра вен нулю, но изза недостаточного числа битов в представлении веще ственных чисел страдает точность вычислений: >>> 0.1 + 0.1 + 0.1 0.3 5.5511151231257827e017 Попытка вывести результат в более дружественной форме мало помо гает, потому что проблема связана с ограниченной точностью пред ставления вещественных чисел: Другие числовые типы 161 >>> print 0.1 + 0.1 + 0.1 0.3 5.55111512313e017 Однако при использовании чисел с фиксированной точностью резуль тат получается точным: >>> from decimal import Decimal >>> Decimal('0.1') + Decimal('0.1') + Decimal('0.1') Decimal('0.3') Decimal("0.0") Как показано в этом примере, числа с фиксированной точностью пред ставления создаются вызовом функции конструктора Decimal из модуля decimal , которому передается строка, содержащая желаемое число зна ков после запятой. Когда в выражении участвуют числа с различной точностью представления, Python автоматически выбирает наиболь шую точность для представления результата: >>> Decimal('0.1') + Decimal('0.10') + Decimal('0.10') Decimal('0.30') Decimal("0.00") Другие инструменты модуля decimal позволяют задать точность пред ставления всех таких чисел и многое другое. Например, объект context из этого модуля позволяет задавать точность (число знаков после запя той) и режим округления (вниз, вверх и т. д.): >>> decimal.Decimal(1) / decimal.Decimal(7) Decimal("0.1428571428571428571428571429") >>> decimal.getcontext( ).prec = 4 >>> decimal.Decimal(1) / decimal.Decimal(7) Decimal("0.1429") Поскольку тип чисел с фиксированной точностью достаточно редко используется на практике, за дополнительными подробностями я от сылаю вас к руководствам по стандартной библиотеке Python. Множества В версии Python 2.4 также появился новый тип коллекций – множест+ во . Поскольку этот тип является коллекцией других объектов, возмож но, его обсуждение выходит за рамки этой главы. Но так как он поддер живает набор математических операций, мы познакомимся с основами его использования. Чтобы создать объектмножество, нужно передать последовательность или другой объект, поддерживающий возмож ность итераций по его содержимому, встроенной функции set (похо жая функция существовала в Python до версии 2.4 во внешнем модуле, но начиная с версии Python 2.4 эта функция стала встроенной): >>> x = set('abcde') >>> y = set('bdxyz') Обратно функция возвращает объект множества, который содержит все элементы объекта, переданного функции (примечательно, что множест 162 Глава 5. Числа ва не предусматривают возможность определения позиций элементов, а кроме того, они не являются последовательностями): >>> x set(['a', 'c', 'b', 'e', 'd']) Множества, созданные таким способом, поддерживают обычные мате матические операции над множествами посредством операторов. Об ратите внимание: эти операции не могут выполняться над простыми последовательностями – чтобы использовать их, нам требуется соз дать из них множества: >>> 'e' in x # Проверка вхождения в множество True >>> x – y # Разница множеств set(['a', 'c', 'e']) >>> x | y # Объединение множеств set(['a', 'c', 'b', 'e', 'd', 'y', 'x', 'z']) >>> x & y # Пересечение множеств set(['b', 'd']) Такие операции удобны при работе с большими множествами данных – пересечение двух множеств содержит объекты, которые присутствуют в обоих множествах, а объединение содержит все объекты из обоих множеств. Ниже приводится более реальный пример применения опе раций над множествами – при работе со списками служащих гипоте тической компании: >>> engineers = set(['bob', 'sue', 'ann', 'vic']) >>> managers = set(['tom', 'sue']) >>> >>> engineers & managers # Кто является и инженером, и менеджером одновременно? set(['sue']) >>> >>> engineers | managers # Все, кто принадлежит к той или иной категории set(['vic', 'sue', 'tom', 'bob', 'ann']) >>> >>> engineers – managers # Инженеры, которые не являются менеджерами set(['vic', 'bob', 'ann']) Кроме того, объект множества предоставляет метод, который реализу ет более экзотический набор операций. Хотя операции над множества ми в языке Python можно реализовать вручную (часто так и делалось в прошлом), встроенные операции над множествами обеспечивают вы сокую скорость выполнения стандартных операций, опираясь на эф фективные алгоритмы и приемы реализации. За дополнительной информацией по множествам обращайтесь к руко водству по стандартной библиотеке языка Python. Другие числовые типы 163 В версии Python 3.0 предлагается форма записи литералов {1, 2, 3} , которая дает тот же эффект, который имеет вызов функции set([1, 2, 3]) и тем самым предоставляет еще один способ созда ния объекта множества. Однако это – будущее расширение язы ка, поэтому за более подробной информацией обращайтесь к при мечаниям к выпуску 3.0. Логические значения Иногда утверждается, что логический тип bool в языке Python по своей природе является числовым, потому что два его значения True и False – это всего лишь целые числа 1 и 0, вывод которых настроен особым об разом. Хотя этих сведений вполне достаточно для большинства про граммистов, тем не менее я предлагаю исследовать этот тип немного подробнее. В версии Python 2.3 появился новый логический тип с именем bool, доступный в виде двух новых встроенных предопределенных имен True и False, которые в свою очередь являются всего лишь подклассом (в объектноориентированном смысле) встроенного целочисленного типа int. True и False ведут себя точно так же, как и целые числа 1 и 0, за исключением того, что для их вывода на экран используется другая логика – они выводятся как слова True и False, вместо цифр 1 и 0 (тех нически, класс bool переопределяет функции str и repr). В соответствии с интерпретацией этих значений, начиная с версии Py thon 2.3, значения выражений логического типа выводятся как слова True и False, а не как числа 1 и 0. Можно считать, что логический тип делает истинные значения более явными. Например, теперь бесконеч ный цикл можно оформить как while True:, а не как менее очевидный while 1:. Точно так же более понятной становится инициализация фла гов, например flag = False. Во всех остальных практических применениях значения True и False можно интерпретировать, как предопределенные переменные с цело численными значениями 1 и 0. В любом случае раньше большинство программистов создавали переменные True и False, которым присваива ли значения 1 и 0, таким образом данный новый тип просто следует это му стандартному приему. Его реализация может приводить к неожи данным результатам: так как True – это всего лишь целое значение 1, которое выводится на экран особым образом, выражение True + 3 даст в языке Python результат 4! Мы еще вернемся к логическому типу в главе 9 (где будет дано опреде ление истины в языке Python) и в главе 12 (где познакомимся с такими логическими операторами, как and и or). |