Почему NaN это не «Not a Number»?

Перевод статьи NaN is not a not a number с сайта https://zerkmsit.wordpress.com/, опубликовано на css-live.ru с разрешения автора — Ivan Kurnosov, переводчик — Друганов Яков (k0d)

При разработке ПО очень важно быть точным при использовании терминов, ведь если все разработчики понимают термины одинаково, то эффективность коммуникации между ними будет высокой. Это как быть с человеком «на одной волне» и «понимать с полуслова».

Один из таких терминов, который часто используется не к месту и без понимания — NaN (Not a Number). Дословно — «нечисло».

Все уходит корнями в «бородатый» стандарт IEEE754-1985 и его преемника IEEE754-2008, там NaN определяется как «особое значение» (множество значений, как мы покажем далее), представляющее собой результат некоторого вычисления, которое не может или не должно быть представлено как конкретное число или такое значение просто неопределено в математическом смысле. Например, arcsin(2) или 0/0. Это также приводит нас к другому открытию: NaN на самом деле числовой тип! Просто это число, которое используется и представляется в некой особоой форме.

Итак, еще раз, по стандарту, NaN это НЕ произвольное значение НЕчислового типа, а число! Это значит, нельзя сказать, что строка "строка" это NaN, так как NaN это на самом деле число.

Все становится еще интереснее, если проверить, а как же представлено NaN в памяти компьютера.

У чисел с плавающей точкой двойной (64 бита) точности (как тип Number в JS) для представления NaN‘ов используется специальный ДИАПАЗОН значений.

А именно: числа (мн.ч.), показатель степени которых равен 0x7FF (hex) или 11111111111 (bin) (11 бит), отведены для представления NaN значений.

Рассмотрим рис. 1.

1

Сейчас все биты равны 0, cледовательно все число равно 0 или 0.0 * 100, это тот самый 0, который нам всем привычен.

А теперь покажем, что такое NaN. Для этого, как мы уже упоминали, поставим все биты показателя степени в 1 (рис. 2)

2

Теперь запишем это число в шестнадцатеричной системе — 0x_7FF_0000000000000. Дамы и господа, перед вами «нечисло» с точки зрения IEEE754.

Более того, остальные 64 - 11 = 53 бита могуть быть любыми, за исключением полностью нулевой мантиссы, которая зарезервирована для представления +Бесконечность при первом знаковом бите равном 0 и -Бесконечность при знаковом бите равным 1 — число будет NaN в любом случае.

Скажем, на рис. 3 по-прежнему NaN

3

Запишем это число в шестнадцатеричной системе — 0x_7FF_B000000000000.

Путем нехитрых комбинаторных расчетов получим, что у чисел с плавающей точкой двойной точности мы имеем (по IEEE754) 253 - 2 чисел, которые будут NaN по стандарту IEEE754. Многовато, не правда ли?

Таким образом, если вы используете NaN как замену для всего, что «нечисло» (строки, значение типа null, объекты и т.д.) — не делайте так. Если нет — поделитесь знанием и помогите остальным быть такими же точными как числа двойной точности как вы.

Материалы для дальнейшего изучения:

http://www.binaryconvert.com/convert_double.html — конвертер чисел двойной точности в десятичные и обратно

https://ru.wikipedia.org/wiki/IEEE_754-2008 — статья в Википедии

P.S. Это тоже может быть интересно:

2 Комментарии
  1. YozhEzhi

    «А именно: числа (мн.ч.)» — ударение поставлено не на ту литеру, видимо.

  2. DarkKain

    переводчик — Друганов Яков
    Ссылочка сломана, лишняя «s» в конце урла.

Оставить комментарий

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

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