Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 47
Текст из файла (страница 47)
Ранее мы уже встречалисьс операциями усечения и округления вниз; мы точно так же можем выполнятьарифметическое округление и производить снижение разрядности при выводе:>>> math.floor(2.567), math.floor(-2.567) # Округление вниз(2, -3)# (до ближайшего наименьшего целого)>>> math.trunc(2.567), math.trunc(-2.567) # Усечение(2, -2)# (отбрасывание дробной части)176Глава 5. Числа>>> int(2.567), int(-2.567)(2, -2)# Усечение# (преобразование в целое число)>>> round(2.567), round(2.467), round(2.567, 2) # Округление ( в Python 3.0)(3, 2, 2.5699999999999998)>>> ‘%.1f’ % 2.567, ‘{0:.2f}’.format(2.567) # Округление при отображении (‘2.6’, ‘2.57’)# (глава 7)В последней инструкции используются операции, с которыми мы уже встречались выше, позволяющие получать строки для вывода и поддерживающие расширенные возможности форматирования.
Кроме того, о чем также говорилосьвыше, предпоследняя инструкция в этом примере вывела бы (3, 2, 2.57), еслибы мы заключили ее в вызов функции print. Несмотря на внешнее сходство получаемых результатов, две последние инструкции имеют существенные отличия – функция round округляет вещественное число и возвращает вещественное число, тогда как операции форматирования строк возвращают строку, а неизмененное число:>>> (1 / 3), round(1 / 3, 2), (‘%.2f’ % (1 / 3))(0.33333333333333331, 0.33000000000000002, ‘0.33’)Интересно, что в языке �������������������������������������������������Python�������������������������������������������существует три способа вычисления квадратных корней: с помощью функции из модуля math, с помощью выражения и спомощью встроенной функции (если вам интересно узнать, какой способ имеетнаивысшую производительность, ознакомьтесь с упражнением в конце четвертой части и с его решением, где приводятся результаты тестирования):>>> import math>>> math.sqrt(144)12.0>>> 144 ** .512.0>>> pow(144, .5)12.0# Функция из модуля math# Выражение# Встроенная функция>>> math.sqrt(1234567890) # Большие числа35136.418286444619>>> 1234567890 ** .535136.418286444619>>> pow(1234567890, .5)35136.418286444619Обратите внимание, что модули из стандартной библиотеки, такие как math,необходимо импортировать, а встроенные функции, такие как abs и round, доступны всегда, без выполнения операции импорта.
Говоря другими словами,модули – это внешние компоненты, а встроенные функции постоянно располагаются в пространстве имен, которое используется интерпретатором Pythonпо умолчанию для поиска имен, используемых программой. В Python 3.0 этопространство имен соответствует модулю с именем builtin (__builtin__ в версии 2.6). В этой книге мы подробнее поговорим о разрешении имен, а пока всякий раз, когда слышите слово «модуль», думайте: «импорт».Модуль random из стандартной библиотеки также необходимо импортировать.Этот модуль предоставляет возможность получения случайных вещественныхчисел в диапазоне от 0 до 1, случайных целых чисел в заданном диапазоне,случайного выбора элементов последовательности и многое другое:Другие числовые типы177>>> import random>>> random.random()0.44694718823781876>>> random.random()0.28970426439292829>>> random.randint(1, 10)5>>> random.randint(1, 10)4>>> 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 появился новый базовый числовой тип: числа с фиксированной точностью представления, формально известные, как числа типа Decimal. Синтаксически такие числа создаются вызовом функции из импортируемого модуля и не имеют литерального представления.
Функционально числас фиксированной точностью напоминают вещественные числа, но с фиксированным числом знаков после запятой, отсюда и название «числа с фиксированной точностью».Например, с помощью таких чисел можно хранить значение, которое всегдабудет иметь два знака после запятой. Кроме того, можно указать, как должны обрабатываться лишние десятичные цифры – усекаться или округляться.И хотя скорость работы с такими числами несколько ниже, чем с обычнымивещественными числами, тем не менее, тип чисел с фиксированной точностьюидеально подходит для представления величин, имеющих фиксированнуюточность, таких как денежные суммы, и для достижения лучшей точностипредставления.ОсновыПредыдущий абзац требует дополнительных пояснений.
Как вы уже знаете(или еще не знаете), вещественная арифметика страдает некоторой долей не-178Глава 5. Числаточности из-за ограничения объема памяти, выделяемого для хранения вещественных чисел. Например, результат следующего выражения должен бытьравен нулю, но точность вычислений страдает из-за недостаточного числа битов в представлении вещественных чисел:>>> 0.1 + 0.1 + 0.1 - 0.35.5511151231257827e-017Попытка вывести результат в более дружественной форме мало помогает, потому что проблема связана с ограниченной точностью представления вещественных чисел:>>> print(0.1 + 0.1 + 0.1 - 0.3)5.55111512313e-017Однако при использовании чисел с фиксированной точностью результат получается точным:>>> from decimal import Decimal>>> Decimal(‘0.1’) + Decimal(‘0.1’) + Decimal(‘0.1’) - Decimal(‘0.3’)Decimal(‘0.0’)Как показано в этом примере, числа с фиксированной точностью представления создаются вызовом функции конструктора Decimal из модуля decimal, которому передается строка, содержащая желаемое число знаков после запятой(при необходимости можно воспользоваться функцией str, чтобы преобразовать вещественное число в строку).
Когда в выражении участвуют числа с различной точностью представления, Python����������������������������������������������������������������������автоматически выбирает наибольшую точность для представления результата:>>> Decimal(‘0.1’) + Decimal(‘0.10’) + Decimal(‘0.10’) - Decimal(‘0.30’)Decimal(‘0.00’)В версии Python 3.1 (которая вышла) существует дополнительная возможность создавать объекты класса Decimal из объектоввещественных чисел путем вызова метода decimal.Decimal.from_float(1.25).
Преобразование выполняется точно, но иногда может порождать большое число десятичных знаков.Глобальная настройка точностиВ модуле decimal имеются дополнительные инструменты, позволяющие задавать точность представления всех таких чисел и многое другое. Например,объект контекста в этом модуле позволяет задавать точность (число знаков после запятой) и режим округления (вниз, вверх и так далее). Точность задаетсяглобально, для всех чисел с фиксированной точностью, создаваемых в текущем потоке управления:>>> import decimal>>> decimal.Decimal(1) / decimal.Decimal(7)Decimal(‘0.1428571428571428571428571429’)>>> decimal.getcontext( ).prec = 4>>> decimal.Decimal(1) / decimal.Decimal(7)Decimal(‘0.1429’)Другие числовые типы179Эта возможность особенно удобна для финансовых приложений, где в денежных суммах копейки представлены двумя десятичными знаками. Числас фиксированной точностью по сути представляют альтернативный способокругления и форматирования числовых значений, например:>>> 1999 + 1.332000.3299999999999>>>>>> decimal.getcontext().prec = 2>>> pay = decimal.Decimal(str(1999 + 1.33))>>> payDecimal(‘2000.33’)Менеджер контекста объектов класса DecimalВ версиях Python�������������������������������������������������������������������������������������������������������������������������� 2.6 и 3.0 (и выше) имеется также возможность временно переопределять точность с помощью инструкции with менеджера контекста.
После выхода за пределы инструкции настройки точности восстанавливаются:C:\misc> C:\Python30\python>>> import decimal>>> decimal.Decimal(‘1.00’) / decimal.Decimal(‘3.00’)Decimal(‘0.3333333333333333333333333333’)>>>>>> with decimal.localcontext() as ctx:...ctx.prec = 2...decimal.Decimal(‘1.00’) / decimal.Decimal(‘3.00’)...Decimal(‘0.33’)>>>>>> decimal.Decimal(‘1.00’) / decimal.Decimal(‘3.00’)Decimal(‘0.3333333333333333333333333333’)При всей полезности этой инструкции для работы с ней требуется больше знаний, чем вы успели приобрести к настоящему моменту. Подробное описаниеинструкции with приводится в главе 33.Поскольку тип чисел с фиксированной точностью достаточно редко используется на практике, за дополнительными подробностями я отсылаю вас к руководствам по стандартной библиотеке Python и к интерактивной справочной системе.
Числа с фиксированной точностью, как и рациональные числа, решаютнекоторые проблемы с точностью, присущие вещественным числам, поэтомусейчас мы перейдем к следующему разделу, чтобы сравнить их.Рациональные числаВ Python 2.6 и 3.0 появился новый числовой тип – Fraction, который реализуетобъекты рациональных чисел. Объекты этого типа в явном виде хранят числитель и знаменатель рациональной дроби, что позволяет избежать неточностии некоторых других ограничений, присущих вещественным числам.ОсновыТип Fraction является своего рода родственником типа Decimal, описанногов предыдущем разделе, и точно так же может использоваться для управленияточностью представления чисел за счет определения количества десятичных180Глава 5.