Введение

Значение для непредставимых данных

В вычислительной технике 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; стандарт не указывает, из какого именно.

Каноническая 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 или возведение в степень приводит к неопределённой форме.