Как внедряются Inf и NaN?

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

В питоне я могу использовать inf а также nan в арифметических и условных выражениях, например:

>>> nan = float('nan')
>>> inf = float('inf')
>>> 1 + inf
inf
>>> inf + inf
inf
>>> inf - inf
nan

Это привело бы меня к мысли, что внутри python есть специальная зарезервированная битовая последовательность для этих двух математических величин, и никакое другое число не может занять эти позиции. Правильно ли мое предположение? Можете ли вы просветить меня в этом отношении?

Если мое предположение верно, то это легко объяснить:

>>> inf == inf
True

Однако это не так:

>>> nan == nan
False

Очевидно, в математике это правильный ответ. Но как Python знает, что он должен выплюнуть False в этом случае?

Кроме того, как реализация Python отличается от реализации Java или C++?

2 ответа

Решение

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

64-битные числа с плавающей точкой IEEE, используемые в CPython в типичных системах, имеют 1 бит для знака, 11 бит для показателя степени и 52 бита для мантиссы. Смотрите https://en.wikipedia.org/wiki/Double-precision_floating-point_format

Если показатель степени содержит 0b11111111111 (все единицы), то число равно либо inf, либо nan, в зависимости от того, что хранится в мантиссе. Python не должен делать ничего особенного для обработки этих случаев. Вы получите те же результаты, сравниваете ли вы числа в Python, C, Java или на ассемблере.

Это не специфичное для Python поведение, это скорее стандартное использование Python с плавающей точкой (и, возможно, все распространенные языки?).

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

Одно уточненное и нетривиальное поведение, NaN!= Все, включая себя.

Зная это, вы можете написать что-то вроде:

def isNaN(f): return f != f
Другие вопросы по тегам