« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга



ПнВтСрЧтПтСбВс
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
    Популярное
Avaya – оптимизация для голоса

Процесс загрузки

Удаленная база данных

CVS - система управления версиями

Собственная статистика поисковых слов (Яндекс, Рамблер, Google,...) на PHP

Проводник Visual Studio.NET по серверу: Server Explorer

Вывод в поле диалогового окна

JavaScript - сценарист по призванию

Функция ShowCursor

Полный мануал по созданию компактного кода




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 163
Пользователей: 0

Статьи:: Интернет технологии :: Python :: Часть I. Python мыслит так, как мыслит новичок :: 3-й час. Арифметические действия в Python



отправить ссылку другу версия для печати  Обсудить на форуме

3-й час. Арифметические действия в Python



3-й час
 

Арифметические действия в Python
 

В этой главе мы изучим основные арифметические действия, которые можно выполнять в Python и IDLE. Хотя они, по сути, предельно простые, но на их основе строятся все сложные математические вычисления, некоторые из которых мы рассмотрим далее в этой книге. Впрочем, чтобы стать хорошим программистом, совершенно необязательно быть доктором математических наук. В большинстве случаев от вас потребуются лишь знания основ математики на уровне средней школы. Если же вам приходилось изучать курс высшей математики, значит, вы подготовлены на все 100%. Так что не бойтесь, смело вперед. Уж, по крайней мере, в этой главе с математикой у вас проблем не будет, только с программированием.
 

Тем, кто не слишком преуспевал в математике, не следует отчаиваться. В старших классах средней школы я, как и все, изучал алгебру и почти провалил ее на экзамене (у меня был откровенно слабый преподаватель, но что еще хуже, я не уделял этому предмету должного внимания). Много позже, на армейском вводном курсе по электронике я наверстал упущенное и усвоил некоторые из основных методов. Через два года после окончания этого курса я стал его преподавать.
 

Сложение и вычитание
 

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

Выполним несколько упражнений с операциями сложения и вычитания. Запустите интерпретатор Python, введя python в приглашении командной строки, а затем в приглашении Python введите 1 + 1. Если после нажатия клавиши <Enter> Python не ответит вам результатом 2, значит, у вас большие проблемы! Теперь попробуйте выполнить более сложные задачи, например сложите нескольких больших чисел, а затем сложите положительные и отрицательные числа. При манипуляциях с числами вам поможет следующая графическая схема. Представьте себе все целые числа в виде точек, расположенных на бесконечной линии с нулем посередине. Тогда, путешествуя вперед или назад с помощью операций сложения и вычитания, вы можете перейти к любому числу. Например, предположим, что вы находитесь в позиции 0 и хотите попасть в позицию -45. Очевидно, что для этого вы должны пропутешествовать назад на 45 точек. Но добраться туда можно двумя способами: можно прибавить отрицательное число или вычесть положительное. Попробуйте проверить оба метода. В окне интерпретатора вы должны получить результаты, показанные на рис. 3.1.
 

Рис. 3.1. 1 + 1
 

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

Не сложно определить максимально допустимое число для калькулятора или счет. Просто пересчитайте число значимых ячеек на табло или число прутиков в раме счет. При использовании компьютера предельность вычислений не столь очевидна. Дело в том, что между внутренним представлением чисел, как его видит компьютер, и тем форматом, в котором число отображается на экране, существуют большие различия. Для внутреннего представления чисел большинство компьютеров использует 32 бита, причем один из этих битов обычно используется для представления знака числа, указывающего, является ли данное число положительным или отрицательным. Поэтому для собственно числового значения остается всего только 31 бит. Таким образом, в Python самым большим допустимым целым знаковым числом является значение 2 147 483 647 (два миллиарда с мелочью).
 

Конечно, вы уже слышали термин бит прежде, но давайте еще раз рассмотрим, что он означает, хотя бы для того, чтобы прибавить вам уверенности. Бит — это одноразрядное значение типа "да-нет", "включено-выключено" или в числовом выражении — 0 или 1. И больше ничего иного. Чтобы представлять большие числа, необходимо объединить вместе несколько таких битов. Это как раз то, чем занимаются современные компьютеры. Они объединяют вместе Свои биты в байты (8 битов) и слова (как правило, 32 бита), из которых затем и складывается весь машинный код.
 

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

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

Рис. 3.2. 32-разрядные числа
 

Шестнадцатеричный формат является одним из способов визуализации двоичных чисел в понятном для человека виде. Двоичные числа проще преобразовывать в шестнадцатеричные, чем в десятеричные. Любое 4-рязрядное двоичное число можно представить одноразрядным шестнадцатеричным. Так, двоичному числу mi будет соответствовать шестнадцатеричное число F. Под термином шестнадцатеричное подразумевается представление числа по основанию 16. Это означает, что ряд шестнадцатеричных цифр следует от О до F, т.е. 0-15 в десятичном представлении. Если вы хотите произвести впечатление на своих друзей и выглядеть суперкрутым компьютерным специали-. стом, пронумеруйте кассеты своей коллекции видеофильмов в шестнадцатеричном формате, начиная с кассеты под номером 0.
 

Отлично, теперь давайте посмотрим, как отреагирует Python, если в математическом действии использовать число, превышающее допустимый предел. Например, давайте прибавим к единице число 9 999 999 999. На рис. 3.3 показано, что в ответ на это скажет Python.
 

Рис. 3.3. Число слишком большое, чтобы Python смог его проглотить
 

М-да-а... Что бы это значило? Именно то, что говорится в сообщении об ошибке: число, которое мы прибавили, оказалось слишком большим для Python, чтобы он мог правильно его обработать. Другими словами, Python попытался преобразовать число 9 999 999 999 в двоичный формат, но для этого ему не хватило битов. Мы получим аналогичный результат, если попытаемся отнять большое число. Так что же остается делать? Оказывается, существует очень простой метод обойти это ограничение: необходимо всего лишь сообщить Python, что он должен обрабатывать большое число именно как большое число. Для этого мы даем Python подсказку — всего лишь добавляем символ L в конце любого большого числа, если полагаем, что оно может вызвать переполнение буфера (именно это подразумевается под нехваткой битов). На рис. 3.4 показан пример такого решения.
 

Рис. 3.4. Снова прибавляем большое число
 

Добавление символа L после любого большого числа сообщает Python, что это длинное число. Длинные числа могут быть сколь угодно большими. Число разрядов ограничено только объемом памяти вашего компьютера и вашим терпением. Теперь давайте поработаем с действительно большими числами. Введите следующее число в основное окно программы IDLE (можете выгрузить из Internet текстовый файл ftp://www.pauahtun.org/pub/googol.txt, в котором содержится это число, или просто введите единицу, а за ней 100 нулей):
 

1000000000000000000000000000000000000000

00000000000000000000000000000000000000000

000000000000000000000000L
 

Добавьте после этого числа знак "плюс" (+), а затем снова вставьте точно такое же число и нажмите клавишу <Enter>. Результат показан на рис. 3.5.
 

Рис. 3.5. Сложение двух длинных чисел
 

Число, состоящее из единицы с сотней нулей, называется гугол (googol). Это название было введено в обиход американским математиком Эдвардом Каснфом (Edward Kasner), a придумано его девятилетним племянником, Милтоном Сироттой (Milton Sirotta).
 

Вы можете складывать обычные целые числа и длинные целые числа без каких бы то ни было проблем. Правилами Python устанавливается, что всякий раз, когда вы выполняете арифметические функции с любыми двумя операндами, меньший операнд приводится к типу большего. Таким образом, если вы суммируете 1 + 100000000000000000000000L, Python автоматически преобразует 1 в 1L.
 

Математические операторы, например суммирования (+) и вычитания (-), оперируют с операндами. Например, выражение "1 + 4" обозначает: "применить оператор суммирования к операндам 1 и 4".
 

Вам придется также столкнуться еще с третьим типом чисел — числа с плавающей запятой. Это числа, в которых есть десятичная запятая, например 1,1 и 3,14159265359. (В англоязычных странах для представления десятичных чисел вместо плавающей запятой используется точка. Обратите на это внимание и не удивляйтесь, что когда в тексте мы говорим о плавающей запятой, то в примерах ставим точку. Примечание: использование запятой в коде программы Python вызовет ошибку.) Иногда в результате сложения и вычитания таких чисел выводится результат, который вы даже и не предполагали получить. Так, к примеру, на рис. 3.6 показано выражение, результатом которого вы, скорее всего, ожидали бы увидеть 0,00001.
 

Рис. 3.6. Вычитание чисел с плавающей запятой
 

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

Умножение, отношение и деление по модулю
 

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

И снова позволю себе повториться — правила выполнения этих операций в Python не очень отличаются от тех, которые вам знакомы со школы. Единственный нюанс, который необходимо всегда учитывать, состоит в том, что тип операнда в значительной степени определяет то, как Python будет обрабатывать числа. Например, деление числа 10 на 4,0, как показано на рис. 3.7, дает ожидаемый результат — 2,5.
 

Рис. 3.7. Деление чисел
 

Но в случае, показанном на рис. 3.8, мы получаем совершенно иной ответ.
 

Рис. 3.8. Еще один пример деления
 

Несовпадение ответов объясняется тем, что в первом случае, указав десятичную запятую (точку) в операнде 4.0, мы сообщили Python, что нам небезразлична информация об остатке деления после десятичной запятой. Во втором случае, опустив десятичную запятую, мы явно указали Python, что нас интересует только целая часть числа. И Python любезно отбросил дробную часть числа (.5), о которой мы сообщили ему, что в ней не нуждаемся. Таким образом, как и в случае с операциями сложения и вычитания, Python определяет формат результата по форматам переданных ему операндов. Поэтому вам следует внимательно относиться к типам операндов. Очень просто потерять десятичную запятую там, где в действительности вы ожидаете ее увидеть. Такая потеря в дальнейшем может привести к неправильной работе программы.
 

Та легкость, с которой при делении можно получить неожиданный или даже неправильный результат, была и остается темой жарких дебатов, ведущихся и по сей день среди участников телеконференций по тематике программирования на Python. Некоторые респонденты доказывают необходимость применения специального оператора, отличного от обычного оператора деления (/), который бы указывал Python, что требуется выполнить целочисленное деление (как показано на рис. 3.8), или наоборот, устанавливающего для результата формат числа с плавающей запятой (рис. 3.7). Так, в качестве специальных операторов деления предлагалось использовать сочетание символов /. для деления только с плавающей запятой и сочетание // — только для целочисленного деления. Но эти предложения не нашли поддержки у Гуидо, хотя он обещал подумать над этим вопросом и внести некоторые изменения в будущие версии Python.
 

Как и в случаях со сложением и с вычитанием, длинные целые числа можно использовать в выражениях умножения и деления (рис. 3.9).
 

Рис. 3.9. Деление и умножение длинных чисел
 

Обратите внимание, что в третьем примере, показанном на рис. 3.9, используется новый оператор, обозначенный символом % — деление по модулю. С помощью этого оператора можно осуществлять деление обычных или длинных целых чисел, причем от полученного результата отбрасывается целая часть числа (частное), а остаток возвращается. Например, выражение 136656000L % 13 возвратит нуль, потому что число 136 656 000 делится на 13 без остатка. Деление по модулю — очень удобное средство, например при вычислении календарных дат. Вот один из примеров. Практически во всех календарях присутствует високосный год, который можно вычислить делением по модулю. А в тех календарях, где високосные годы отсутствуют, ситуация настолько сложна, что без деления по модулю вообще не обойтись. Примером последнего может быть календарь Майя. С нашим григорианским календарем ситуация попроще, так как високосные годы в нем присутствуют. В юлианском календаре, от которого собственно и произошел григорианский, действует очень простое правило високосного года: любой год, значение которого делится без остатка на 4, является високосным. Правило григорианского календаря вносит поправку в эту формулировку, утверждая, что годы столетий (1700, 1900 и т.д.) являются високосными только в том случае, если они делятся без остатка на 400. На рис. 3.10 показано, как определить, является ли 2000-й год високосным.
 

Рис. 3.10. Определение високосного года
 

Год 2000 — високосный, а 1900 — нет. Я как-то читал один детектив, в котором следователь разбил "железное" алиби подозреваемого после того, как сообразил, что 1900-й год не был високосным. Я уже не помню в деталях ни саму историю, ни ее автора, но факт остается фактом — иногда бывает важно быстро определить, является ли указанный год високосным.
 

Существует специальная функция, которую можно использовать для возвращения частного и остатка от деления. Функция divmod(x,y) возвращает результаты выполнения двух действий: х / у и х % у. Вы можете проверить это, введя в окне IDLE команду print divmod (53,13). Пара результатов будет показана в виде (4,1). В Python всегда возвращаются группы результатов, о чем мы поговорим позже.
 

Округление, функции floor() и ceil()
 

В этом разделе мы будем иметь дело исключительно с числами в формате с плавающей запятой. Во всех случаях, когда необходимо выполнить любую математическую операцию над числами с плавающей запятой, следует помнить об ограничениях, связанных с базовым представлением этих чисел компьютером. Компьютеры оперируют с числами только в двоичном формате, т.е. с основанием 2. В числах с основанием 2 присутствуют только две цифры — 0 и 1. Это идеальная система счисления для компьютеров, поскольку значения 0 и 1 могут быть представлены простым двух-позиционным переключателем. Электролампочка, тумблер, электросхемы на лампах или транзисторах — все это примеры двухпозиционных переключателей. Преобразование целых чисел, представленных на базе одной основы, к формату с другой основой является относительно простой процедурой, которой занимаются компьютеры и неплохо справляются с момента их появления. При смене основания числа не теряется ни "капли" информации. Всегда можно преобразовать числа к другой основе без какого-либо округления. Например, десятичному числу 15 точно соответствует шест-надцатеричное число F, и любое другое десятеричное число однозначно соответствует определенному шестнадцатеричному, восьмеричному, двоичному и т.д. В таком случае говорят, что при преобразовании целых чисел потери точности не происходит.
 

Но это утверждение справедливо только для целых чисел. Все меняется, стоит только вставить в число десятичную запятую. Способы, с помощью которых в компьютерах осуществлялось представление чисел с плавающей запятой, исторически были разнообразными, сложными и довольно противоречивыми. Только в течение последних нескольких лет появилось что-то похожее на стандарт представления чисел этого типа. Тем не менее многие полагают, что даже этот стандарт, IEEE-64, полон ловушек и недостатков. К сожалению, чтобы полностью раскрыть эту увлекательную тему, понадобится написать отдельную книгу не меньшего объема, чем данная. Но вряд ли такая книга выйдет, так как найдется не много людей, которые проявили бы к ней интерес. Уж больно это специфический вопрос для узкого круга специалистов. Пока вполне достаточно будет сообщить вам, что проблем в этом вопросе множество, а их решение сопряжено со значительными трудностями.
 

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

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

Рис. 3.11. Несколько примеров преобразования типов
 

Преобразования типов часто сопровождаются округлением значения. Иногда требуется округлить результат к большему значению, иногда — к меньшему. Для этого существуют специальные методы округления, позволяющие контролировать данную операцию: floor() и ceil(). Помните, как раньше мы уже импортировали модуль sys? Точно так же всякий раз, когда вам понадобится использовать математические функции, следует импортировать модуль math. Но теперь мы воспользуемся другой инструкцией импортирования модулей (рис. 3.12).
 

Рис. 3.12. Функции floor() и ceil()
 

Данная инструкция импортирования позволяет обращаться к членам модуля непосредственно, без указания имени модуля. Если бы мы импортировали модуль math иначе, то чтобы вызвать число л (пи), нам пришлось бы вводить math.pi. Точно так же для обращения к функциям floor () и ceil () пришлось бы использовать вызовы math.floor () и math, ceil (). Многие люди предпочитают не использовать инструкцию from x import *, так как это небезопасно. Дело в том, что имена в импортированном модуле могут конфликтовать с теми, которые программист определил в своей программе. Впрочем, вероятность появления таких конфликтов невелика. Кроме того, ничего страшного не произойдет, просто интерпретатор сообщит вам об ошибке. С другой стороны, профессиональный программист никогда не станет импортировать модуль с помощью import *, если он недостаточно с ним знаком. Даже если ничего плохого не произойдет, это дурной тон программирования. Прежде чем что-либо импортировать, следует достать документацию на этот модуль и хорошо с ней познакомиться.
 

На рис. 3.12 показано практически все, что необходимо знать для правильного использования функций округления и преобразования типов. Только проверьте, чтобы количество открывающих круглых скобок соответствовало количеству закрывающих. И еще на один момент хотелось бы обратить ваше внимание. Посмотрите, как функция long () принимает в качестве аргумента другую функцию ceil (). Это важный момент, который необходимо хорошо запомнить: вместо чисел в качестве аргументов функций допускается использовать другие функции, которые обрабатывают свои аргументы.
 

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

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

Возведение в степень, как вы должны помнить со школы, это, попросту говоря, умножение некоторого числа на себя определенное количество раз. Например, 22 означает умножить два на два, или возвести два в квадрат, что в результате даст 4. Точно так же 23 означает, что надо умножить два на два и на два, или возвести двойку в куб, что в результат даст 8.
 

Экспотенциальное представление чисел, или, выражаясь более формально, форма записи чисел с плавающей запятой, использует показатель степени, чтобы при работе с очень большими числами избежать записи с многократным повторением нулей. Ранее, на рис. 3.6, был показан пример, в котором мы вычитали 10.0 - 9. 99999 и получили неожиданный ответ: 9.99999999962е-006, тогда как предполагали увидеть 0.00001. Экспотенциальная форма записи содержит две части: показатель степени и дробную часть (которую иногда неправильно называют мантиссой). Что касается нашего удивительного ответа, то е-006 как раз и является показателем степени, а 9. 99999999962 — ее дробная часть. Символ е как раз и указывает начало показателя степени (от английского exponent). Значение -006 — это фактическое значение показателя степени. Число, записанное подобным образом, обычно произносится как "9.99999999962 на 10 в минус шестой". Все очень просто, затруднение может состоять только в том, чтобы выговорить все эти девятки после десятичной запятой. Отрицательное значение показателя степени сообщает нам, что необходимо разделить единицу на значение нашего основания, т.е. на 10, определенное количество раз. К примеру, 10-1 является тем же самым, что и дробь 1/10 или 0,1. Показатель степени -6 в нашем примере означает разделить единицу на 10 шесть раз, или 1/1 000 000. Этой дроби соответствует число 0.000001. Чтобы убедиться в этом, посмотрите на рис. 3.13.
 

Рис. 3.13. Отрицательные показатели степени
 

Обратите внимание на последний результат, выведенный на экране, — число 0 .000010. Это значение чрезвычайно близкое к тому, что мы ожидали увидеть с самого начала. Помните, что я говорил раньше о погрешностях округления при сложении и вычитании, которые имеют тенденцию существенно возрастать? Когда вы оперируете с очень маленькими числами, порядка 10-6, эти ошибки суммируются и проявляют себя в значительной степени.
 

Экспотенциальное представление чисел весьма широко используется в программировании и научно-исследовательских работах. Поэтому имеет смысл познакомиться с этой формой записи поближе. Чаще всего вам могли встречаться следующие значения: 103, т.е. 1000, 106, или миллион, 109 — миллиард и 1012 — триллион. (Интересно, что термины, применяемые к числам свыше миллиона, в разных странах могут иметь различные значения. Так, согласно американской терминологии, слово биллион (billion) обозначает миллиард.) А помните единицу, за которой следовала сотня нулей — гугол? Мы использовали это число в примерах несколько раньше. Так вот, для записи гугола в экспотенциальном представлении существуют два способа. Первый — в виде 10100, а второй — в виде 1010 . Но в обоих случаях мы имеем одно и то же число. После того как Каснер ввел в обиход термин гугол, другой математик предложил число под названием гуголплекс (googolplex), которое соответствует 10гугол. Боюсь, нам не хватит бумаги, чтобы записать это число в обычном виде. Информация для любознательных: на Web-странице этой книги можно найти программу на языке Python, которая выводит на печать числа гугол и гуголплекс. Она будет выполняться до тех пор, пока у вас не лопнет терпение, или не исчерпается компьютерная память, или свободное пространство на жестком диске компьютера, или пока Земля не упадет на Солнце (неизвестно, что произойдет первым). На рис. 3.14 показан быстрый метод вывода числа гугол в Python.
 

Рис. 3.14. Вывод числа гугол
 

Применение скобок
 

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

Python, как и все другие языки программирования, имеет сложную систему правил, называемых правилами приоритета операторов. С учетом этих правил опытный программист может управлять порядком выполнения математических формул без множества скобок. Это может повысить читабельность формул, если, конечно, соблюсти меру и следовать логике. Можно было бы и вообще обойтись без скобок. Для этого всего лишь необходимо запомнить каких-то 20—30 сложных правил, переписать свои математические выражения таким образом, чтобы они удовлетворяли этим правилам, но не соответствовали никакой человеческой логике, и тогда в вашем коде не разберется ни один шпион. Когда будете писать свои формулы, найдите золотую середину.
 

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

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

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

Когда я делал только первые шаги в программировании, я несколько раз обжигался на правилах приоритета выполнения операторов, так как они не всегда следуют общепринятой логике. Скобки в этом плане более надежны, так как обладают абсолютным приоритетом. Рассмотрим применение скобок на простом примере, показанном на рис. 3.15. Если нам нужно найти отношение суммы на число, то следующее выражение будет неправильным: 400 + 1 / 3. Чтобы исправить ситуацию, заключите сумму 400 + 1 в скобки.
 

Рис. 3.15. Пример использования скобок
 

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

Некоторые нюансы и секреты
 

Одной из особенностей Python, которую необходимо учитывать при обработке чисел любого типа, является механизм выполнения функций floor () и ceil () для отрицательных аргументов. По выполнению этих функций Python отличается от языков С и C++, поэтому если вы работали с любым из этих языков, то должны быть начеку, чтобы предупредить появление ошибок. Данная проблема проиллюстрирована на рис. 3.16.
 

Рис. 3.16. Округление отрицательных чисел
 

В языке С применение функции f loor () к аргументу pi дает результат 3, но если применить ее к значению -pi, то получим —3, а в Python — —4. Если же используется функция ceil О, то получится -4 и —3 соответственно. Почему так происходит? По определению, в обоих языках функция floor () осуществляет "округление вниз". Почему же тогда получаются разные результаты? Дело в том, что эти языки по-разному понимают, что такое "округление вниз". В случае с Python слово вниз подразумевает меньше, аналогично тому, как 0,0001<0<10000 и число 0.0000000000001 меньше числа 0.0001. Тогда как в С меньше означает ближе к нулю. Таким образом, в Python число —4 "лежит ниже", чем —3.14159265359. При целочисленном делении результат получается таким же, как при применении функции floor (). Результат округляется к меньшему числу, а не к тому, которое находится ближе к нулю.
 

Эти несостыковки в логике языков могут привести к неожиданным проблемам. Например, работая в С, я написал функцию, которая вычисляла разницу в днях между григорианским и юлианским календарями. Эта разница носит название отклонение и является константой в промежутке от 100 до 200 лет. Я перенес эту функцию в Python и быстренько проверил ее работоспособность. Казалось, что все работает нормально. Но через два-три дня после этого мне подвернулся случай опробовать ее на отрицательных датах. Результаты ее работы утверждали, что до 0-го года не было никаких отклонений. (В этой программе годы до нашей эры выражались отрицательными цифрами.) Это была явная ошибка. Я исследовал код функции и вышел на строку, которая содержала следующее выражение: devn = 2 - leaper + -(leaper/4). В этом выражении devn и leaper являются переменными, назначение которых состоит в сохранении значений. (С переменными вы познакомитесь в следующей главе.) Переменная leaper содержит значение столетия. Если это значение выражалось отрицательной величиной, то результат отношения leaper/4 округлялся до меньшего значения, а не до того, которое ближе к нулю. Поэтому программа работала в С, но допускала ошибки в Python.
 

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

Если у вас богатый опыт программирования, заставьте себя внимательно изучить средства Python, вчитываясь во все детали, чтобы не допускать подобные оплошности.
 

Полезное свойство Python, которое лично мне очень понравилось, — встроенная поддержка длинных целых чисел. Я был разочарован, работая в С и C++ над календарем Майя. Эти языки строго отслеживают тип данных, и чтобы иметь возможность обрабатывать в программе как обычные, так длинные целые числа, приходилось дважды переписывать код для обоих типов. Для Python достаточно явно указать длинное число и для обработки его использовать те же функции, что и для обычного числа. Конечно, Python стал бы еще удобнее, если бы вообще не видел разницы между обычными и длинными числами. Действительно, различие между этими типами чисел совершенно условно и связано только с объемом памяти, предоставляемым для сохранения значения. Гуидо обещал в скором будущем сделать прозрачным переход от типа к типу. А пока вам придется проявлять внимательность с арифметическими операциями, при выполнении которых возможно переполнение целых 32-битовых знаковых чисел. Если вам, к примеру, случится столкнуться с календарем народов Майя, то вы не успеете и глазом моргнуть, как преодолеете двухмиллиардный (плюс мелочь) предел.
 

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

Резюме
 

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

Для обобщения материала посмотрите табл. 3.1, в которой представлены все математические операторы, используемые в Python. Некоторые из этих операторов будут подразумевать совершенно иное действие, когда будут применяться к объектам, не являющимся числами. Мы будем подробно рассматривать особенности применения этих операторов по мере освоения нового материала.
 

Таблица 3.1. Математические операторы в Python
 

       
 
Символ
 
Значение
 
 
 
+
 
Сложение/тождество
 
 
 
-
 
Вычитание/отрицание
 
 
 
*
 
Умножение
 
 
 
/
 
Деление
 
 
 
%
 
Деление по модулю
 
 
 
* *
 
Возведение в степень
 
 
 
divmod (x, у)
 
Функция, возвращающая значения х / у и х % у
 
 
       

 

Практикум
 

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

Что лучше, компьютер или счеты?
 

Дело вкуса, привычек и цели применения. Счетами проще отбиваться от грабителя, пытающегося залезть в вашу кассу.
 

Когда было изобретено экспоненциальное представление чисел?
 

Два первых случая использования такого представления чисел были зафиксированы незадолго до 1890 года, если только это не более позднее добавление переводчиков. По-настоящему первое указание на эту форму записи было зафиксировано в журнале Jean's Theoretical Mechanics ("Теоретическая механика") за 1907 г., где масса Земли приводится в виде 6х1027 г. За эту цитату мы должны быть благодарны Джону Харперу (John Harper) из университета Виктория, Веллингтон, Новая Зеландия (Victoria University, Wellington).
 

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

  1. Как можно сообщить интерпретатору Python, что некоторое число имеет формат длинного целого числа?
     

    а) long("10000000000000000000000000000000000000")
     

    б) 100000000000000000000000000000000L
     

    в) string.atol("100000000000000000000000000000")
     

    г) любое целое число/1L
     

  2. Что произойдет, если умножить число с плавающей запятой на длинное целое число?
     

    а) Вы получите сообщение об ошибке OverflowError.
     

    б) Python преобразует результат в комплексное число.
     

    в) Python сообщит вам, что в любом случае вам не понять ответ.
     

    г) Когда длинное целое число состоит примерно из 300 (или более) цифр, Python вместо числового ответа посылает строку 1.#INF (или inf — для Linux). В остальных случаях он выдает ответ, используя экспоненциальное представление.
     

  3. Если двоичное число по основанию 2, а шестнадцатеричное по основанию 16, то что такое восьмеричное число и где оно используется?
     

    а) Числа с основанием 32; используются программистами Macintosh.
     

    б) Это понятие не имеет никакого отношения к числам; термин восьмеричное (octal) — это название символа #.
     

    в) Числа с основанием 8; используются программистами UNIX.
     

    г) Числа с основанием 8; но никто их не использует.
     

Ответы
 

  1. Можно использовать все указанные методы.
     
  2. г. Для чисел с плавающей запятой в Windows и Linux максимальным установлено значение с показателем степени ±308. Это достаточно большое (или достаточно маленькое) число. При выходе за эти пределы библиотеки, поддерживающие вычисления с плавающей запятой, возвращают стандартный символ бесконечности.
     
  3. в. Восьмеричное число — конечно же, это число с основанием 8. И числа в таком формате действительно главным образом используют программисты, разрабатывающие приложения для UNIX. Наиболее наглядным примером применения таких чисел является программа chmod для UNIX, которая позволяет изменять права доступа к файлам. А символ #, действительно, имеет необычное название — октоторп (octothorpe).
     

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

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

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

  1. Большие конечные и бесконечные числа: http://www.sci.wsu.edu/math/faculty/hudelson/mose.r.html
     
  2. Познакомьтесь с числом газиллион (gazillion): http://www.straightdope.com/mailbag/mgazilli.html
     
  3. Как получить число гуголплекс: http://WWW/~fp/Tools/GetAGoogol.html
     
  4. Названия чисел разного порядка (от маленьких до больших): http://studwww.rug.ас.be/~hvernaev/FAQ/node2 6.html
     
  5. И снова число гуголплекс: http: //www/~fp/Topls/Googool.html (лучший узел, касающийся этого вопроса)
     
  6. Число л и его друзья: http://www.go2net.com/internet/useless/useless/pi.html
     
  7. Эпоха расцвета индейцев Майя и эпоха глифов: http://www.pauahtun.org/calglypn.html
     

Попробуйте выяснить, насколько большим должно быть число, чтобы вызвать сбой в работе Python или "подвесить" ваш компьютер? (Только сначала сделайте резервные копии всех файлов.)








Подгрузка через AJAX HTML-кода, содержащег....

AJAX

При разработке CMS S.Builder наша команда активно использовала AJAX. Теперь вот решили поделиться накопленным опытом. Начнем с этого хабратопика. Не буду здесь затрагивать различные фреймворки и библиотеки. Свой код всегда роднее. Для работы с AJAX-ом в S.Builder написана библиотека sbAJAX. Можете качать и пользоваться :). В этом файле есть функция sbEvalJS. Для тех, кто не знает, объясню. При подгрузке через AJAX и вставке на страницу HTML-кода, содержащего JavaScript, JavaScript выполняться не будет или полезут баги. Эта функция как раз решает поставленную задачу.


Подробнее... | Рубрика: AJAX | Добавлено: 19.11.2008

Обзор нового релиза самой мощной Ajax библ....

AJAX

Хотя наш обзор немного запоздал, оригинальный Dojo 1.2 вышел в релизной версии ещё 6-го октября, но сейчас мы наверстаем упущенное. И так, Dojo Toolkit — это самая мощная и гибкая ajax-библиотека из всех, что есть на рынке, она активно развивается и имеет большое комьюнити. Кстати, это самое комьюнити, совместно с компанией Sitepen, имеет ещё несколько проектов, среди которых и Cometd и некоторые другие, не менее интересные, о которых мы скоро вам расскажем. Сегодня же все внимание на флагманский продукт — Dojo 1.2.


Подробнее... | Рубрика: AJAX | Добавлено: 19.11.2008

Firebug 1.3 и 1.4 alpha — что нового и инт....

Вебмастеру

Если вы профессиональный веб-разработчик и постоянно имеете дело с разработкой и отладкой сложных AJAX приложений, то наверняка знаете и используете Firebug — плагин для браузера Firefox, предназначенный для отладки и исследования веб-приложений. Текущая его версия, 1.2х достаточно стабильная и функциональна, чтобы помочь в 99% проблем, которые могут возникнуть при разработке. Но и этот инструмент не лишён если не недостатков, то некоторых фич, которые могли бы облегчить работу. И даже идеальный инструмент можно сделать ещё более идеальным, как бы это не звучало.


Подробнее... | Рубрика: Вебмастеру | Добавлено: 19.11.2008

Остальные статьи:

Релиз Microsoft Silverlight 2.0. Что новог...
XML документация в C#
Курсоры в MySQL 5
Microsoft опубликовала подробности о сесси...
Microsoft делится подробностями о том, что...
Тестируем новый javascript от нового брауз...
MySQL Query Cache
Использование провайдеров компиляции в As...
Чего мы ждем от C# 4.0
Delphi 2009 и C++Builder 2009
Джоэл Спольски и Джеф Этвуд запустили новы...
Поиск кода Google /* что нового? */
10 jQuery скриптов для улучшения интерфейс...
Генераторы отчетов FastReport 4 и QuickRep...
День программиста — набор стерeотипов
Индусские програмисты
Вышел Django 1.0
Портативная версия Google Chrome Portable
Исходные коды .Net Frameword 3.5 SP1 для о...
Пишем правильный online WYSIWYG-редактор


Цитата дня (все,добавить):

Портал фрилансеров

работа на дому


    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование


Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия