Шаг 51.
Python: сборник рецептов.
Числа, даты и время. Работа с бесконечными значениями и NaN

    На этом шаге мы рассмотрим особенности реализации таких вычислений.

Задача

    Вам нужно создать или протестировать такие значения с плавающей точкой: бесконечность, минус бесконечность, NaN (not a number, "не число").

Решение

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

>>> a = float('inf')
>>> b = float('-inf')
>>> c = float('nan')
>>> a
inf
>>> b
-inf
>>> c
nan
>>> 

    Чтобы проверить, не является ли значение таким, используйте функции math.isinf() и math.isnan(). Например:

>>> import math
>>> math.isinf(a)
True
>>> math.isnan(c)
True
>>> 


Обсуждение

    За подробностями об этих специальных значениях с плавающей точкой вы можете обратиться к спецификации IEEE 754. Однако здесь есть несколько хитрых деталей, о которых нужно знать. Особенное внимание нужно обратить на темы, связанные со сравнениями и операторами.

    Бесконечные значения распространяются в вычислениях согласно математическим правилам. Например:

>>> a = float('inf')
>>> a + 45
inf
>>> a * 10
inf
>>> 10 / a
0.0
>>> 

    Однако некоторые операции не определены и выдают NaN. Например:

>>> a = float('inf')
>>> a/a
nan
>>> b = float('-inf')
>>> a + b
nan
>>> 

    Значения NaN распространяются через все операции, не возбуждая исключений. Например:

>>> c = float('nan')
>>> c + 23
nan
>>> c / 2
nan
>>> c * 2
nan
>>> math.sqrt(c)
nan
>>> 

    Тонкость с NaN заключается в том, что они никогда не будут равны друг другу. Например:

>>> c = float('nan')
>>> d = float('nan')
>>> c == d
False
>>> c is d
False
>>> 

    По причине этого единственный безопасный способ проверить значение на NaN - это использовать math.isnan(), как показано в данном рецепте.

    Иногда программисты хотят изменить поведение Python таким образом, чтобы при возникновении в ходе вычислений бесконечностей или NaN возбуждались исключения. Для такого изменения поведения может быть использован модуль fpectl, но он не включен в стандартную поставку Python, является платформозависимым и на самом деле предназначен только для программистов-экспертов.


Этот модуль был удален, начиная с версии Python 3.7.

    На следующем шаге мы рассмотрим вычисления с дробями.




Предыдущий шаг Содержание Следующий шаг