Введение
Значение для непредставимых данных
В вычислительной технике NaN (/n//æ//n/), аббревиатура от Not a Number (не число), является специальным значением числового типа данных (часто числа с плавающей запятой), которое не определено как число, например, результат деления 0 на 0. Систематическое использование NaN было введено стандартом IEEE 754 для арифметики с плавающей запятой в 1985 году, вместе с представлением других бесконечных величин, таких как бесконечности. В математике результат 0/0 обычно не определяется как число и поэтому может быть представлен NaN в вычислительных системах. Квадратный корень из отрицательного числа не является действительным числом и поэтому также представляется NaN в соответствующих вычислительных системах. NaN также может использоваться для представления отсутствующих значений в вычислениях. Предусмотрены два типа NaN: тихие NaN и сигнальные NaN. Тихие NaN используются для распространения ошибок, возникающих в результате недопустимых операций или значений. Сигнальные NaN могут поддерживать расширенные возможности, такие как объединение численных и символьных вычислений или другие расширения базовой арифметики с плавающей запятой.
Тихо.
В целом, тихие NaN, или qNaN, не приводят к возникновению дополнительных исключений, так как они распространяются в ходе большинства операций. Однако исключение недействительной операции возникает в некоторых операциях, которые не возвращают значение с плавающей точкой, например, при преобразовании форматов или определенных операциях сравнения.
Операции с полезной нагрузкой
IEEE 754 2019 рекомендует реализовать операции getPayload, setPayload и setPayloadSignaling, стандартизируя доступ к полезным данным для упрощения использования в приложениях. Согласно справочному документу IEEE 754 2019, данная рекомендация должна интерпретироваться как "обязательная для новых реализаций, с учётом обеспечения обратной совместимости".
Кодирование
В формате обмена IEEE 754 NaN идентифицируются по специфическим, заранее определенным битовым паттернам, уникальным для NaN. Знак не имеет значения. Бинарный формат NaN представлен экспоненциальным полем, заполненным единицами (как и значения бесконечности), и некоторым ненулевым числом в поле мантиссы (чтобы отличить их от значений бесконечности). Оригинальный стандарт IEEE 754 1985 года (IEEE 754 1985) описывал только бинарные форматы чисел с плавающей запятой и не указывал, как должно быть помечено состояние сигнализации/тишины. На практике наиболее значимый бит поля мантиссы определял, является ли NaN сигнальным или тихим. В результате появились две различные реализации с обратным значением: большинство процессоров (включая процессоры Intel и AMD x86, Motorola 68000, AIM PowerPC, ARM, Sun SPARC и, опционально, новые процессоры MIPS) устанавливали бит сигнализации/тишины в ненулевое значение, если NaN тихий, и в нулевое, если NaN сигнализирующий. Таким образом, на этих процессорах бит представляет собой флаг; в NaN, генерируемых процессорами PA RISC и старыми процессорами MIPS, бит сигнализации/тишины равен нулю, если NaN тихий, и ненулевому, если NaN сигнализирующий. Таким образом, на этих процессорах бит представляет собой флаг. Первый вариант предпочтительнее, поскольку он позволяет реализации подавить сигнализирующий NaN, просто установив бит сигнализации/тишины в 1. Обратное невозможно при втором варианте, поскольку установка бита сигнализации/тишины в 0 может привести к бесконечности. Пересмотры стандарта IEEE 754 2008 и 2019 годов содержат формальные требования и рекомендации по кодированию состояния сигнализации/тишины. Для бинарных форматов обмена наиболее значимый бит поля мантиссы используется исключительно для различения тихих и сигнализирующих NaN. (Это требование было добавлено в пересмотре 2019 года.) Более того, это должен быть флаг. То есть этот бит ненулевой, если NaN тихий, и нулевой, если NaN сигнализирующий. Для десятичных форматов обмена, закодированных как в двоичном, так и в десятичном виде, NaN идентифицируется установкой пяти верхних битов комбинационного поля после бита знака в единицы. Шестой бит поля является флагом. То есть этот бит равен нулю, если NaN тихий, и ненулевому, если NaN сигнализирующий. Для соответствия стандарту IEEE 754 2008 значение бита сигнализации/тишины в современных процессорах MIPS теперь настраивается через поле NAN2008 в регистре FCSR. Эта поддержка является необязательной в MIPS Release 3 и обязательной в Release 5. Состояние/значение остальных битов поля мантиссы стандартом не определено. Это значение называется «полезной нагрузкой» NaN. Если операция имеет один вход NaN и передает его на выход, полезная нагрузка NaN в результате должна быть такой же, как и у входного NaN (это не всегда возможно для бинарных форматов, когда состояние сигнализации/тишины кодируется флагом, как описано выше). Если есть несколько входных NaN, полезная нагрузка NaN в результате должна быть взята из одного из входных NaN; стандарт не указывает, из какого именно.
most processors (including those of the Intel and AMD's x86 family, the Motorola 68000 family, the AIM PowerPC family, the ARM family, the Sun SPARC family, and optionally new MIPS processors) set the signaling/quiet bit to non zero if the NaN is quiet, and to zero if the NaN is signaling. Thus, on these processors, the bit represents an flag;
in NaNs generated by the PA RISC and old MIPS processors, the signaling/quiet bit is zero if the NaN is quiet, and non zero if the NaN is signaling. Thus, on these processors, the bit represents an flag. The former choice has been preferred as it allows the implementation to quiet a signaling NaN by just setting the signaling/quiet bit to 1. The reverse is not possible with the latter choice because setting the signaling/quiet bit to 0 could yield an infinity. The 2008 and 2019 revisions of the IEEE 754 standard make formal requirements and recommendations for the encoding of the signaling/quiet state. For binary interchange formats, the most significant bit of the significand field is exclusively used to distinguish between quiet and signaling NaNs. (This requirement has been added in the 2019 revision.) Moreover, it should be an flag. That is, this bit is non zero if the NaN is quiet, and zero if the NaN is signaling. For decimal interchange formats, whether binary or decimal encoded, a NaN is identified by having the top five bits of the combination field after the sign bit set to ones. The sixth bit of the field is the flag. That is, this bit is zero if the NaN is quiet, and non zero if the NaN is signaling. For IEEE 754 2008 conformance, the meaning of the signaling/quiet bit in recent MIPS processors is now configurable via the NAN2008 field of the FCSR register. This support is optional in MIPS Release 3 and required in Release 5. The state/value of the remaining bits of the significand field are not defined by the standard. This value is called the 'payload' of the NaN. If an operation has a single NaN input and propagates it to the output, the result NaN's payload should be that of the input NaN (this is not always possible for binary formats when the signaling/quiet state is encoded by an flag, as explained above). If there are multiple NaN inputs, the result NaN's payload should be from one of the input NaNs; the standard does not specify which.
Каноническая NaN
В ряде систем существует концепция "канонического NaN", при которой одно конкретное значение NaN выбирается в качестве единственного возможного qNaN, генерируемого операциями с плавающей точкой, не имеющими NaN в качестве входных данных. Это значение обычно представляет собой тихий NaN с нулевой полезной нагрузкой и произвольно заданным битом знака. На RISC V операции с плавающей точкой всегда генерируют только канонический NaN, даже если NaN передается в качестве операнда (полезная нагрузка не распространяется). ARM может активировать режим "NaN по умолчанию" для обеспечения такого поведения. WebAssembly демонстрирует аналогичное поведение, хотя и допускает два канонических значения. В Java подобный подход применяется "в большинстве случаев". Использование ограниченного числа представлений NaN позволяет системе использовать другие возможные значения NaN для неарифметических целей, наиболее важной из которых является "упаковка NaN", то есть использование полезной нагрузки для хранения произвольных данных. (Эта концепция "канонического NaN" отличается от концепции "канонического кодирования" в стандарте IEEE 754.)
Определение функции
Существуют различные мнения относительно правильного определения результата численной функции, принимающей тихое NaN в качестве входных данных. Одна из точек зрения заключается в том, что NaN должен распространяться на выход функции во всех случаях, чтобы сигнализировать об ошибке. Другая точка зрения, принятая в целом стандартами ISO C99 и IEEE 754 2008, заключается в том, что если функция имеет несколько аргументов и выход однозначно определяется всеми входными данными, не являющимися NaN (включая бесконечность), то это значение должно быть результатом. Таким образом, например, значение, возвращаемое и , равно +∞. Проблема особенно актуальна для функции возведения в степень 1=pow(x, y) = xy. Выражения 0⁰, ∞⁰ и 1∞ считаются неопределёнными формами, когда они встречаются в качестве пределов (как ∞ × 0), и вопрос о том, следует ли определять ноль в нулевой степени как 1, вызывает разногласия. Если выход считается неопределённым при неопределённом параметре, то должен возвращать qNaN. Однако математические библиотеки обычно возвращают 1 для pow(1, y) для любого действительного числа y, и даже когда y — бесконечность. Аналогично, они возвращают 1 для pow(x, 0) даже когда x равен 0 или бесконечности. Версия стандарта IEEE 754 2008 года утверждает, что и должны возвращать 1, поскольку они возвращают 1 независимо от того, что используется вместо тихого NaN. Более того, ISO C99 и позднее IEEE 754 2008 выбрали указание 1=pow(−1, ±∞) = 1 вместо qNaN; причина этого выбора объясняется в обосновании стандарта C: «В целом, C99 избегает результата NaN, когда доступно полезное числовое значение. Результат — +∞, поскольку все большие положительные числа с плавающей точкой являются чётными целыми числами». Чтобы удовлетворить тех, кто предпочитает более строгую интерпретацию поведения функции возведения в степень, стандарт 2008 года определяет две дополнительные функции: pown(x, n), где показатель должен быть целым числом, и powr(x, y), которая возвращает NaN, когда параметр является NaN или возведение в степень приводит к неопределённой форме.