Что выведет float 21 2
Перейти к содержимому

Что выведет float 21 2

  • автор:

 

Разбираемся в числах с плавающей точкой (часть 0)

Здравствуйте, хабровчане. Я давно увлекаюсь темой регистров с плавающей точкой. Меня всегда волновало то, как происходит вывод на экран и т.д. Помню, давным-давно в универе реализовывал свой класс чисел с плавающей точкой, состоящих из 512 бит. Единственное, что я не мог никак реализовать — это вывод на экран.

Как только у меня появилось свободное время, я взялся за старое. Завел себе тетрадку и пошло-поехало. Хотелось додуматься до всего самому, лишь иногда заглядывая в стандарт IEEE 754.
И вот что из всего этого вышло. Интересующихся прошу под кат.

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

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

В сегодняшней статье для примера я буду использовать 32-битные регистры. Числа с двойной точностью (64-битные) работают абсолютно по той же логике.

Сначала поговорим о том, как хранятся числа с плавающей точкой. Старший 31 бит у нас знаковый. Единичка значит, что число отрицательное, а ноль, соответственно наоборот. Далее идут 8 бит экспоненты. Эти 8 битов представляют из себя обычное беззнаковое число. И в самом конце идут 23 бита мантиссы. Для удобства будем обозначать знак как S, экспоненту как E, а мантиссу, как ни странно, M.

Получаем общую формулу

У мантиссы принято считать один неявный единичный бит. То есть мантисса будет представлять из себя 24 бита, но так как старший 23-й бит всегда единица, то его можно не записывать. Таким образом это «ограничение» будет давать нам единственность представления любого числа.

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

Давайте попробуем показать это на наглядном примере:

Представим число 3.625 в двоичном виде. Поначалу разобьем это число на степени двойки.

Степень старшей двойки равна единице. E – 127 = 1. E = 128.

0 1000000 11010000000000000000000

Вот и все наше число.

Попробуем также и в обратную сторону. Пусть у нас есть 32 бита, произвольные 32 бита.

0 10000100 (1)11011100101000000000000

В скобочках указан тот самый неявный старший бит.

Сначала вычислим экспоненту. E = 132. Соответственно степень старшей двойки будет равна 5. Итого имеем следующее число:

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

Для удобной конвертации я накидал небольшую программу на языке C.

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

Можно выразиться иначе. Два соседних числа с плавающей точкой будут отличаться на 2 ^ (E — 127 — 23). То есть на разницу, равную значению младшего бита.

В качестве доказательства можете поменять main в коде и скомпилировать еще раз.

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

[ Сборник задач ]
Тема 2.Числа с плавающей
точкой

Python Workbook Cover

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

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

  1. Структуру числа с плавающей точкой (какие его части сохраняются в памяти и сколько бит занимает каждая); типа float ;
  2. Способы преобразования в целые числа ( trunc , floor , ceiling , round );
  3. Правила округления.

Читайте также

Two

Сначала вычислим выражение, а потом определим его тип при помощи функции type().

Решение – Интерактивный режим
>>> 3 + 3.0 + 4
10.0
>>> type(10.0)
<class ‘float’>

Как видим, получается тип float, т.е. число с плавающей точкой.

2. Из каких трех элементов состоит тип данных float?

Числа типа float состоят из:

– знака (+ или -);
– экспоненты, обозначающей степень десятки (например, е+5);
– значимых чисел (до и после запятой).

-11.03е+5 – типичная запись вещественного числа. Она аналогична варианту -11.03 * 10 ** 5 или -1103000.0.

В результате всегда получим целое число. Знак сохраняется, целочисленная часть остается, а вся дробная часть отрезается.

4. Какой самый простой способ получения нуля с плавающей точкой (т.е. числа 0.0)? Использовать можно только функцию float().

Первое, что приходит на ум: передать 0 в качестве аргумента внутрь функции float().

Решение – Интерактивный режим
>>> float(0)
0.0

Однако, все еще проще: если не передавать аргумент, то по умолчанию ставится 0.

Решение – Интерактивный режим
>>> float()
0.0

5. Каким методом можно проверить, является ли заданное вещественное число целым?

С нашей точки зрения 4.0 и 4 – равные числа, и оба являются целыми, так как 0 после точки не несет никакой смысловой нагрузки. В Python эти числа также равны, но первое относится к типу float, а второе – к int.

Для ответа на вопрос можно использовать 2 варианта:

A. Преобразовать число в тип int и сравнить его с самим собой.

Решение – Интерактивный режим
>>> int(4.0) == 4.0
True

Б. Так как в вопросе использовано слово «метод», то логичнее воспользоваться соответствующим методом.

Решение – Интерактивный режим
>>> (4.0).is_integer()
True

6. Какие типы данных можно преобразовать в числа с плавающей точкой?

К вещественным числам можно преобразовать строки и числа:

Решение – Интерактивный режим
>>> float(8)
8.0

Решение – Интерактивный режим
>>> float(8.0)
8.0

– булевы значения (т.к. они относятся, в том числе, к типу int)

Решение – Интерактивный режим
>>> float(False)
0.0

Решение – Интерактивный режим
>>> float(‘4.6’)
4.6

– экземпляры классов Decimal и Fraction

Решение – IDE
from decimal import Decimal
from fractions import Fraction
print(float(Decimal(10.4)))
print(float(Fraction(5, 2)))

Результаты:
10.4
2.5

7*. В чем суть банковского округления в Python (стандарт IEEE 754)?

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

Что функция int(), что метод trunc() из модуля math дают одинаковые результаты. По факту, это аналоги, реализующие следующий механизм: отсекается дробная часть и возвращается целочисленное значение с сохранением знака.

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

Решение – IDE
from math import trunc
print(int(5.2))
print(trunc(5.2))
print(int(5.2) == trunc(5.2))

Результаты:
5
5
True

Что выведет float 21 2

0.000003190524921592 (FN)

0.07001511752605438 (MW)

0.1500047892332077 (FT)

0.38000398874282837 (WW)

0.45001640915870667 (BS)

0.999925971031189 (BS)

Числа в Python

Когда мы хотим представить информацию о количестве деревьев в саду, остатке на банковской карте или же провести какие-либо математические расчеты, мы используем числа. В Python числа представлены сразу несколькими родственными категориями типов. Сюда относятся целые ( int ), вещественные ( float ) и комплексные ( complex ) числа. Если возможностей базовых типов не хватает, всегда можно воспользоваться числовыми расширениями в виде модулей decimal или fractions. Все перечисленные числовые типы довольно легко преобразуются между собой, а математические операции с ними интуитивно понятны и производятся по общепринятым правилам математики.

Целые числа

По умолчанию для записи литералов целых чисел в Python используется десятичная система счисления, однако разрешается записывать их в двоичной, восьмеричной и шестнадца­теричной системах счисления. При этом следует помнить, что вне зависимости от использу­емого формата представления, результат все равно будет отображаться в десятич­ном виде (см. пример №1 ).

Пример №1. Литералы целых чисел в Python.

Как видно из примера №1 , синтаксис записи целых чисел в разрешенных системах счисления должен иметь следующий вид.

  • В десятичной системе счисления целые числа записываются в виде привычной нам последовательности цифр от нуля до десяти, например, 0 , -33 , +127 .
  • В двоичной системе счисления запись целого числа должна начинаться с нуля и латинской буквы B в верхнем или нижнем регистре (т.е. 0b или 0B ), после чего должна идти последовательность нулей и единиц. Например, 0b01101 , 0B1011 , -0b1001 . Если будут использованы другие цифры, интерпретатор сгенерирует сообщение об ошибке.
  • В восьмеричной системе счисления целое число должно начинаться с нуля и латинской буквы O в верхнем или нижнем регистре (т.е. 0o или 0O ), после чего должна идти последовательность цифр от нуля до семи ( 01234567 ). Например, 0o77 , 0O35 , -0O174 . Если будут использованы цифры не входящие в данный диапазон, интерпретатор сгенерирует сообщение об ошибке.
  • В шестнадцатеричной системе счисления запись целого числа должна начинаться с нуля и латинской буквы X в верхнем или нижнем регистре (т.е. 0x или 0X ), после чего должны идти символы последовательности 0123456789ABCDEF , представляющих данную систему счисления. При этом буквы также разрешается использовать в любом регистре. Например, 0x7F , 0XDD5A , -0xfF9 . Если будут использованы символы не входящие в данный диапазон, интерпретатор сгенерирует сообщение об ошибке.

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

  • bin(int_num) – преобразует целое число в двоичную систему счисления, возвращая строку с представлением литерала числа в этой системе.
  • oct(int_num) – преобразует целое число в восьмеричную систему счисления, возвращая строку с представлением литерала числа в этой системе.
  • hex(int_num) – преобразует целое число в шестнадцатеричную систему счисления, возвращая строку с представлением литерала числа в этой системе.
  • int(obj) – конструктор типа int может использоваться как с одним, так и с двумя аргументами. Когда указан только один аргумент, функция пытается преобразовать объект в целое число в десятичной системе счисления, а в случае невозможности такого преобразования возбуждает соответствующее исключение. При этом, если объект obj является вещественным числом, оно преобразуется в целое путем усечения дробной части, например, int(21.302) вернет 21 .
  • int(num_str, base=10) – если указано два аргумента, то первый аргумент должен быть строковым представлением целого числа в системе счисления с указанным основанием base . Разрешается использовать системы счисления с основаниями от 2 до 36 . При этом префикс 0b , 0o или 0x у строкового представления числа можно опускать. Если же точно известно, что в строковом представлении числа присутствует соответствующий префикс, второму аргументу разрешается передавать ноль, т.к. интерпретатор сможет определить систему счисления переводимого числа по указанному префиксу. В случае невозможности преобразования строки в целое число функция возбуждает соответствующее исключение (см. пример №2 ).

Пример №2. Перевод целых чисел между СС.

Итак, функции bin(int_num) , oct(int_num) и hex(int_num) принимают целые числа и возвращают строковые представления этих чисел в соответствующих системах счисления. Если же требуется обратное преобразование в десятичную систему, то следует передавать числа функции int(num_str, base=10) , предварительно приведя число к строке ( num_str = str(num) ) и указав основание системы счисления переводимого числа.

 

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

Далее. Целые числа в Питоне отличаются тем, что их размер в принципе ограничивается лишь доступной памятью. Т.е. они поддерживают длинную арифметику и могут быть сколь угодно большими (см. пример №3 ). При этом следует помнить, что при обработке очень больших чисел приходится жертвовать скоростью их обработки.

Пример №3. Пример очень большого целого числа.

Также следует отметить, что в отличие от других типов чисел над целыми числами в Python можно производить битовые операции, перечень которых представлен для ознакомления в порядке возрастания их приоритета в таблице №4 . Подробнее данный вопрос мы рассмотрим позже, когда будем рассматривать битовые операции.

Таблица №4. Список битовых операций, применимых к целым числам.

Также у типа int имеется несколько дополнительных методов:

  • int.bit_length() – метод возвращает количество бит, которое необходимо для представления числа в памяти в двоичном виде, без учета знака и незначащих (лидирующих) нулей;
  • int.to_bytes(length, byteorder, *, signed=False) – метод возвращает массив байтов, который соответствует данному числу;
  • int.from_bytes(bytes, byteorder, *, signed=False) – метод класса, который возвращает целое число, соответствующее указанному массиву байтов.

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

Вещественные числа

Что касается записи литералов вещественных чисел (по-другому чисел с плавающей точкой), то в Python для них используется привычный нам математический синтаксис: сперва записывается знак числа (плюс можно не указывать), затем последовательность цифр целой части, разделительная точка и последовательность цифр дробной части. Например, 0.33 , .33 , 0.0 , .0 , -123.45 , -.123 . Также допустима запись вещественных чисел в экспоненциальной форме. При этом для представления степени 10 n используется латинская буква E в верхнем или нижнем регистре (т.е. e или E ), следующий за ней необязательный знак плюс или обязательный знак минус, а также сам показатель степени в виде положительного целого числа или нуля (см. пример №5 ).

Пример №5. Литералы вещественных чисел в Python.

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

Пример №6. Точность представления вещественных чисел в Python.

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

Пример №7. Побочные эффекты сложения вещественных чисел в Python.

Как видим, на первый взгляд результат действительно получился неожиданным (не забываем про кнопку «Результат» ). Однако все верно. Ведь в данном случае при переводе десятичных чисел в двоичную систему компьютер не смог перевести их точно, округлив результат так, чтобы получившееся двоичное число поместилось в пределах выделяемого для хранения вещественного числа объема памяти. В результате у нас получилось число несколько меньшее, чем 0.8 . Но, повторимся, это не проблема Python , это проблема математики и невозможности во всех случаях осуществить точный перевод чисел из одной системы счисления в другую.

Не стоит сравнивать вещественные числа, доверяя их точности до последнего знака.

В заключение данного пункта перечислим дополнительные методы типа float .

  • float.as_integer_ratio() – метод возвращает кортеж из пары целых чисел, которые представляют собой числитель и знаменатель наименьшей дроби, равной данному вещественному числу. Если вещественное число отрицательное, то первое число в возвращаемом кортеже будет со знаком минус. При этом второе число всегда положительное (см. пример №8 ).
  • float.is_integer() – метод возвращает True , если дробная часть вещественного числа равна нулю.
  • float.hex() – метод возвращает строковое представление числа с плавающей точкой в шестнадцатеричной системе счисления. При этом следует иметь в виду, что экспонента в таком представлении обозначается буквой p , т.к. буква e представляет собой допустимый символ в 16 -ной системе счисления.
  • float.fromhex(float_num_str) – этот метод класса осуществляет преобразование строкового представления вещественного числа float_num_str в шестнадца­теричной системе счисления обратно в вещественное число в десятичной системе счисления.

Пример №8. Дополнительные методы типа float.

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

Комплексные числа в Python представлены типом complex , который хранит два вещественных числа: первое представляет собой действительную часть комплексного числа, а второе – мнимую. Как и принято в математике, действительная и мнимая части литерала комплексного числа объединяются знаком плюс или минус (см. пример №9 ). Однако за мнимой частью в Python следует символ j , как это принято в инженерии (в математике мнимая единица обозначается через i ).

Пример №9. Литералы комплексных чисел в Python.

Как видно из примера, если действительная часть комплексного числа равна 0 , ее можно опустить. Кроме того, отдельные части комплексного числа доступны в виде атрибутов real и imag , а получить сопряженное данному комплексное число можно изменив знак мнимой части при помощи метода complex.conjugate() .

Вполне возможно, что сталкиваться с комплексными числами вам придется довольно редко, однако иметь представление о наличии такого типа все-таки не помешает.

Математические операции в Python

Все известные нам со школы математические операции полностью поддерживаются в Python . Перечислим их и рассмотрим примеры.

  • x + y – сложение двух чисел.
  • x — y – вычитание двух чисел.
  • x * y – умножение двух чисел.
  • x / y – деление двух чисел. При делении вещественных и целых чисел (даже без остатка) результат всегда является вещественным числом. Если же в делении присутствуют комплексные числа, интерпретатор возвращает комплексный результат (см. пример №10 ).
  • x // y – деление с округлением вниз. Например, 1//2 = 0 , -1//2 = -1 , 1//-2 = -1 , -1//-2 = 0 .
  • x % y – операция возвращает остаток от деления целых и вещественных чисел. Если оба числа целые, то возвращается целочисленный остаток (тип int ). Например, 5%3 = 2 , -5%3 = 1 (т.к. -5 = 3*(-2) + 1 ), 6%3 = 0 . Если хотя бы одно число вещественное, остаток от деления также возвращается в вещественном виде (тип float ), при чем из-за неточности представления вещественных чисел результат может оказаться неточным. Например, 5.2%3 = 2.2 (все в порядке), -5.2%3 = 0.7999999999999998 (получили неточный результат, хотя ожидали 0.8 , т.к. -5.2 = 3*(-2) + 0.8 ). Что касается комплексных чисел, то для них операция неприменима.
  • +x – операция используется в основном для повышения удобочитаемости кода, т.к. по факту она ничего не делает.
  • -x – инверсия знака числа отличного от нуля, т.е. изменение плюса на минус или наоборот. Для нуля ничего не происходит.
  • x ** y – возведение в степень. Отметим, что 0**0 = 1 .

Пример №10. Базовые математические операции в Python.

Что касается математических выражений, в которых используются сразу несколько операций, то для их группировки предназначены круглые скобки (см. пример №11 ). При этом внутри скобок приоритет отдается сперва возведению в степень ( x**y ), затем равносильно умножению ( x*y ), делению ( x/y ), делению с округлением вниз ( x//y ) и получению остатка от деления ( x%y ); в конце равнозначно выполняются сложение ( x + y ) и вычитание ( x — y ). Более подробно о приоритете операторов в Python (и не только математических) мы поговорим позже.

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

Пример №11. Математические выражения в Python.

Обратите внимание, что при наличии в одном выражении целых и вещественных чисел, интерпретатор при необходимости осуществляет приведение целых чисел к типу float , т.е. к более объемлющему типу (в математике целые числа являются подмножеством вещест­вен­ных, а те в свою очередь принадлежат множеству комплексных чисел).

В дополнение к математическим операторам Python предоставляет и ряд полезных встроенных функций, позволяющих, например, найти модуль числа или округлить его (см. пример №12 ). Опять же, перечислим их и приведем краткое описание.

  • divmod(x, y) – возвращает кортеж (x//y, x%y) . При этом для комплексных чисел она не предназначена.
  • pow(x, y) – возвращает x в степени y (аналог x ** y ).
  • abs(x) – возвращает абсолютное значение (модуль) числа x .
  • round(x, n) – округляет число до n -го разряда после запятой. Если аргумент n не указан, то число округляется до ближайшего целого.
  • max(num_1, num_2, . num_n) – возвращает максимальное из двух и более чисел.
  • min(num_1, num_2, . num_n) – возвращает минимальное из двух и более чисел.
  • sum(num_1, num_2, . num_n) – возвращает сумму двух и более чисел.
  • int(x) – приведение числа к типу int .
  • float(x) – приведение числа к типу float .
  • complex(re, im=0) – приведение к типу complex . Аргумент im (мнимая часть будущего комплексного числа) можно не передавать, тогда он по умолчанию будет равен нулю.

Пример №12. Встроенные математические функции в Python.

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

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

  • x < y – выражение вернет True , если x строго меньше y .
  • x > y – выражение вернет True , если x строго больше y .
  • x <= y – выражение вернет True , если x меньше или равно y .
  • x >= y – выражение вернет True , если x больше или равно y .
  • x == y – выражение вернет True , если x равно y (в программировании один знак равно означает присвоить , поэтому для обозначения равенства используются два знака равно).
  • x != y – выражение вернет True , если x не равно y .

Использование операторов сравнения показано в примере №13 .

Пример №13. Операторы сравнения чисел в Python.

В дополнение к базовому оператору присваивания = в Python применяется целый ряд комбинированных операторов присваивания, которые объединяют операцию присваивания с другой операцией. В общем случае выражение присваивания с комбини­рованным оператором x op= y можно считать сокращенной записью выражения x = x op y , где вместо op следует подставлять один из арифметических операторов. Например, x += y является сокращенной записью выражения x = x + y , в котором к значению переменной x прибавляется значение переменной y , после чего результат присваивается переменной x . Использование некоторых комбинированных операторов присваивания показано в примере №14 .

Пример №14. Комбинированные операторы присваивания в Python.

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

Модуль math

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

Для начала давайте рассмотрим представленные в модуле math математические константы и функции проверки чисел на принадлежность к ним.

  • math.pi – представляет значение числа π с точностью, которая зависит от конкретной платформы. Мы его помним, как число 3.14 .
  • math.tau ( чит. тау) – представляет удвоенное значение числа π с точностью, которая зависит от конкретной платформы. Т. о. τ – это отношение радиуса окружности к ее длине. Прибли­зительно оно равно 6.28 .
  • math.e – представляет значение числа e с точностью, которая зависит от конкретной платформы. Мы его помним, как число 2.72 .
  • math.inf (от англ. infinity) – представляет положительную бесконечность. Отметим, что значение является типом float и может быть получено вызовом конструктора float(‘inf’) . Для получения отрицательной бесконечности следует использовать унарный оператор — (см. пример №15 ). К значению inf в математике приводит, например, операция деления на 0 .
  • math.nan (от англ. not a number) – представляет значение не число , которое также является типом float и может быть получено вызовом конструктора float(‘nan’) . К значению nan приводят недопустимые математические операции (например, извлечение корня четной степени из отрицательного числа на множестве вещественных чисел) или выход за допустимый диапазон значений для данной математической функции.
  • math.isinf(x) – возвращает True , если x является отрицательной или положительной бесконечностью, или False в противном случае.
  • math.isnan(x) – возвращает True , если x является значением nan , или False в противном случае.
  • math.isfinite(x) – возвращает False , только если x является nan , inf или -inf . Во всех остальных случаях функция возвращает True .

Пример №15. Математические константы модуля math.

Что касается конкретно функций модуля math , то в нем представлены различные функции теории чисел, степенные, логарифмические, тригонометрические, гиперболические и ряд других функций. Все мы их здесь рассматривать не будем, однако краткое описание некоторых из них приведем в списке ниже. Остальные в случае необходимости всегда можно с легкостью найти в разделе «Numeric and Mathematical Modules» справочника стандартной библиотеки в описании модуля math (или cmath для комплексных чисел). Итак.

  • math.ceil(x) – возвращает x , округленное вверх до ближайшего целого (см. пример №16 ).
  • math.floor(x) – возвращает x , округленное вниз до ближайшего целого.
  • math.trunc(x) – возвращает целую часть x , полностью отсекая дробную.

Пример №16. Функции модуля math (часть 1).

  • math.factorial(x) – возвращает факториал неотрицательного целого числа x . Отметим, что факториалы чисел 0 и 1 принимаются равными 1 .
  • math.sqrt(x) – возвращает квадратный корень из неотрицательного числа x (см. пример №17 ).
  • math.log(x[, base]) – возвращает логарифм числа x по основанию base . Аргумент base можно опустить, тогда функция вернет натуральный логарифм числа x .

Пример №17. Функции модуля math (часть 2).

  • math.sin(x) – возвращает синус угла x , значение которого задано в радианах. Отметим, что для косинуса угла функция имеет вид math.cos(x) (см. пример №18 ).
  • math.tan(x) – возвращает тангенс угла x , значение которого задано в радианах.
  • math.asin(x) – возвращает арксинус числа x . Для аркосинуса нужно использовать функцию math.acos(x) , а для арктангенса – math.atan(x) .
  • math.degrees(x) – преобразует угол x из радиан в градусы.
  • math.radians(x) – преобразует угол x из градусов в радианы.

Пример №18. Функции модуля math (часть 3).

Обязательно откройте модуль math в справочнике стандартной библиотеки и хотя бы бегло просмотрите весь список доступных функций. Кстати, не забываем, что получить его можно и программно через dir(math) .

Модуль decimal

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

Пример №19. Создание чисел фиксированной точности.

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

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

Числа типа Decimal обычно используются в определенном контексте, который подразумевает использование установленной точности представления, методики округления (вверх, вниз и т.д.) и некоторых других настроек (см. пример №20 ).

Пример №20. Изменение точности представления чисел Decimal.

Все настройки среды для арифметических операций получаемые при помощи метода decimal.getcontext() доступны для изменения. Кроме того, для установки нового контекста можно использовать метод decimal.setcontext() . С этим и некоторыми другими методами для работы с контекстами вы можете ознакомиться в модуле decimal стандартной библиотеки (см. раздел «Numeric and Mathematical Modules» ).

Отметим, что все арифметические операции, включая комбинированные, применимы и к числам Decimal . Однако модуль math для них неприменим. В тоже время некоторые функции, присутствующие в модуле math , реализованы как методы типа Decimal (см. пример №21 ).

Пример №21. Операции с числами Decimal.

Модуль fractions

Еще одним числовым типом в Python является тип Fraction . Он реализует объекты рациональных чисел, которые явным образом хранят числитель и знаменатель рациональной дроби (см. пример №22 ), что опять же при необходимости помогает избежать недостатков вещественных чисел.

Пример №22. Создание рациональных чисел.

В примере мы создали объекты рациональных чисел, указав в конструкторе Fraction в первом выражении числитель и знаменатель, а во втором передав ему вещественное число и строковое представление вещественного числа. Кроме того, рациональную дробь можно создать и конвертацией типа Decimal . В любом случае после создания объекты рациональных чисел могут участвовать в арифметических операциях, как обычные числа (см. пример №23 ).

Пример №23. Операции с рациональными числами.

Познакомиться с рациональными числами и их методами более подробно вы можете в модуле fractions стандартной библиотеки Python (см. раздел «Numeric and Mathematical Modules» ).

Краткие итоги параграфа

  • Числа в Python представлены тремя базовыми типами: целые числа int , числа с плавающей точкой float и комплексные числа complex . Также посредством стандартной библиотеки доступны два расширения в виде чисел с фиксированной точностью Decimal и рациональных чисел Fraction .
  • Для записи литералов целых чисел используется десятичная система счисления, однако разрешается записывать их в двоичной (например, 0b101 ), восьмеричной (например, -0o175 ) и шестнадцатеричной (например, 0xF5A ) системах счисления. Для перевода целых чисел из одной системы счисления в другую предназначены встроенные функции bin(int_num) , oct(int_num) , hex(int_num) , int(num_str, base=10) .
  • Целые числа поддерживают длинную арифметику и могут быть сколь угодно большими. При этом следует помнить, что при обработке очень больших чисел приходится жертвовать скоростью их обработки.
  • Для записи литералов вещественных чисел используется привычный нам математический синтаксис, например, -2.57 , 0.0 , .28 (ноль перед точкой можно опускать). Также допустима запись вещественных чисел в экспоненциальной форме, например, 1.2345e2 (т.е. 1.2345*10 2 ) или -1.2345E-3 (т.е. -1.2345*10 -3 ).
  • В обычных условиях точность вещественных чисел ограничивается максимум 17 значащими цифрами. Поэтому не стоит сравнивать их, доверяя точности до последнего знака.
  • Комплексные числа в Python хранят два вещественных числа: первое представляет собой действительную часть комплексного числа, а второе – мнимую. Например, -0.4+7j , 2-1.45j или 3.1j (нулевую действительную часть можно опускать).
  • В Python поддерживаются все известные нам со школы математические операции: сложение x + y , вычитание x — y , умножение x*y , деление x/y , деление с округлением вниз x//y , получение остатка от деления x%y , возведение в степень x**y . Стоит помнить, что некоторые операции не применимы к комплексным числам.
  • В дополнение к базовому оператору присваивания = в Python применяется целый ряд комбинированных операторов присваивания, которые объединяют операцию присваивания с другой операцией. Например, += , -= , *= , /= , //= , %= , **= . Как видим, в общем случае выражение присваивания с комбини­рованным оператором x op= y можно считать сокращенной записью выражения x = x op y , где вместо op следует подставлять один из арифметических операторов.
  • Для сравнения чисел используются операторы < , > , <= , >= , == (равно), != (не равно).
  • Помимо стандартных арифметических операций имеется и ряд полезных встроенных функций для работы с числами: divmod(x, y) – возвращает кортеж (x//y, x%y) , pow(x, y) – возвращает x в степени y , abs(x) – возвращает модуль числа x , round(x, n) – округляет число до n -го разряда после запятой, max(num_1, num_2, . num_n) , min(num_1, num_2, . num_n) и sum(num_1, num_2, . num_n) – соответственно возвращают максимальное, минимальное и сумму из двух и более чисел.
  • Если встроенных функций недостаточно, можно воспользоваться расширением math стандартной библиотеки, которое обеспечивает доступ к широкому кругу математических функций и констант, которые определены стандартом языка C . Для комплексных чисел следует использовать модуль cmath .
  • Для случаев, когда требуется повышенная точность вычислений, в Python предусмотрены дополнительные типы числовых объектов: числа с фиксированной точностью Decimal , которые позволяют устанавливать требуемую точность вычислений, способ округления и некоторые другие параметры, а также рациональные числа Fraction , которые явным образом хранят числитель и знаменатель рациональной дроби. Оба модуля доступны в стандартной библиотеке Python в разделе «Numeric and Mathematical Modules» .

Вопросы и задания для самоконтроля

1. Какие из представленых литералов чисел относятся к типу int , а какие к типу float : 3.4 , 0 , 5.0 , 0.0 , 123+4.1j , 795 ? Проверьте типы программно. Показать решение.

Ответ. Тип int : 0 и 795 . Тип float : 3.4 , 5.0 , 0.0 .

2. Определите системы счисления целых чисел 0x1101 , 0b1101 , 0o755 , 0X755 и 755 , записанные в исходном коде программы. Показать решение.

Ответ. Двоичная СС: 0b1101 ; восьмеричная СС: 0o755 ; десятичная СС: 755 , шестнадцатеричная СС: 0x1101 и 0X755 .

3. Какая операция над целыми числами никогда не дает в результате целое число? Показать решение.

Ответ. Результат деления целых чисел всегда имеет тип float , даже при делении без остатка. Например, 15/5 вернет 3.0 , а не 3 .

4. Как можно получить действительную и мнимую части комплексного числа? А как получить число, сопряженное к данному комплексному числу? Показать решение.

Ответ. Отдельные части комплексного числа доступны в виде атрибутов real и imag , а получить сопряженное данному комплексное число можно изменив знак мнимой части при помощи метода complex.conjugate() .

5. Вычислите устно и программно значения выражений 2*(3 + 4) и 2*3 + 4 . Объясните результаты. Показать решение.

Ответ. В Python как и в математике первыми выполняются действия в скобках, поэтому 2*(3 + 4) = 14 . Если скобки отсутствуют, то первыми выполняются операции с более высоким приоритетом. А так как приоритет умножения выше приоритета сложения, то 2*3 + 4 = 10 .

6. Каким будет тип результата вычисления выражения 7 — 3 + 2.0 и почему? Проверьте свой ответ программно. Показать решение.

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

7. Каким будет остаток от деления числа 63 на число 5 ? Проверьте свой ответ программно. Показать решение.

8. Как получить доступ к функциям модуля math ? Показать решение.

Ответ. Нужно импортировать его при помощи инструкции import math .

9. Исправьте в коде пять ошибок (по одной в каждом блоке). Показать решение.

10. Дополнительные упражнения и задачи по теме расположены в разделе «Числа и математические выражения» нашего сборника задач и упражнений по языку программирования Python .

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *