Почему typeof NaN возвращает "число"?

просто из любопытства.

Это не кажется очень логичным, что typeof NaN номер. Прямо как NaN === NaN или возврат false. Является ли это одной из особенностей javascript, или для этого есть причина?

Edit: спасибо за ваши ответы. Это не простая вещь, чтобы получить их голову вокруг, хотя. Чтение ответов и wiki я понял больше, но все же, предложение, как

сравнение с NaN всегда возвращается неупорядоченный результат, даже при сравнении с самим собой. Предикаты сравнения либо сигнализируют, либо не сигнализируют, сигнальные версии сигнализируют недопустимое исключение для таких сравнений. Предикаты равенства и неравенства не сигнализируют, поэтому x = x, возвращающий false, можно использовать для проверки, является ли x тихим NaN.

просто голова кружится. Если кто-то может перевести это на человеческий (в отличие от, скажем, математического) читаемый язык, я был бы благодарен.

20 ответов


Это означает не число. Это не особенность javascript, а общий принцип информатики.

от http://en.wikipedia.org/wiki/NaN:

существует три вида операции которые возвращают Нэн:

операции с NaN как минимум один операнд

неопределенной формы

  • подразделения 0/0, ∞/∞, ∞/-∞, -∞/∞, и -∞/-∞
  • умножения 0×∞ и 0×-∞
  • мощность 1^
  • дополнения ∞ + (-∞), (-∞) + ∞ и эквивалентные вычитания.

реальные операции со сложными результатами:

  • квадратный корень из отрицательного числа
  • логарифм отрицательного числа
  • касательная нечетного кратного 90 градусов (или π/2 радианов)
  • обратный синус или Косинус числа, которое меньше -1 или более значительный чем +1.

все эти значения могут быть разными. Простой тест для NaN-это тест value == value ложно.


Ну NaN еще числовое тип, несмотря на то, что на самом деле обозначает не число :-)

NaN просто означает, что конкретное значение не может быть представлено в пределах ограничений числового типа (хотя это можно сказать для всех чисел, которые должны быть округлены, чтобы соответствовать, но NaN - Это особый случай).

конкретной NaN не считается равным другому NaN потому что они могут быть разные значения. Однако,NaN по-прежнему является типом номера, как 2718 или 31415.


Что касается вашего обновленного вопроса, чтобы объяснить в терминах непрофессионала:

сравнение с NaN всегда возвращает неупорядоченный результат даже при сравнении с самим собой. Предикаты сравнения либо сигнализируют, либо не сигнализируют, сигнальные версии сигнализируют о недопустимом исключении для таких сравнений. Предикаты равенства и неравенства не сигнализируют, поэтому x = x, возвращающее false, может использоваться для проверьте, является ли x тихим NaN.

все это означает (разбито на части):

сравнение с NaN всегда возвращает неупорядоченный результат даже при сравнении с самим собой.

в основном, a NaN не равно любому другому числу, включая другой NaN, и даже .

предикаты сравнения либо сигнализируют, либо не сигнализируют, сигнализация версии сигнализируют о недопустимом исключении для таких сравнений.

попытка выполнить сравнение (меньше, больше и т. д.) операций между NaN и другое число может либо привести к возникновению исключения (сигнализация), либо просто получить false в результате (без сигнализации или тихо).

предикаты равенства и неравенства не сигнализируют, поэтому x = x, возвращающий false, можно использовать для проверки, является ли x тихим бабушка.

тесты на равенство (равно, не равно) никогда не сигнализируют, поэтому их использование не вызовет исключения. Если у вас есть обычный номер x, потом x == x всегда будет правдой. Если x это NaN, потом x == x всегда будет ложным. Это дает вам способ обнаружить NaN легко (спокойно).


стандарт ECMAScript (JavaScript) указывает, что Numbers are IEEE 754 поплавки, которые включают в себя NaN как возможное значение.

ECMA 262 5e раздел 4.3.19: числовое значение

примитивное значение, соответствующее 64-разрядному двоичному формату двойной точности IEEE 754.

ECMA 262 5e раздел 4.3.23: NaN

числовое значение, которое является IEEE 754 Значение "не-число".

IEEE 754 Википедии

стандарт IEEE для арифметики с плавающей запятой является техническим стандартом, установленным Институтом инженеров электротехники и электроники и наиболее широко используемым стандартом для вычисления с плавающей запятой [...]

стандарт определяет

  • арифметические форматы: наборы двоичных и десятичных данных с плавающей запятой, которые состоят из конечных чисел (включая знаковые нули и субнормальные числа), бесконечностей и специальные значения" не число " (NaNs)

[...]


typeof NaN возвращает 'number' потому что:

  • спецификация ECMAScript говорит, что тип номера включает NaN:

    количество 4.3.20 типа

    набор всех возможных числовых значений, включая специальное " Не-число" (NaN) значения, положительная бесконечность и отрицательная бесконечность

  • так typeof возвращает соответственно:

    11.4.3 оператор typeof

    производства объект unaryexpression : typeof объект unaryexpression is оценивается следующим образом:

    1. пусть вал быть результатом оценки объект unaryexpression.
    2. если тип(вал) is ссылка, тогда
      1. если IsUnresolvableReference(вал) is правда, вернуть "undefined".
      2. пусть вал быть метод getValue(вал).
    3. возвращает строку, определяемую тип(вал) согласно таблице 20.

                    Table 20 — typeof Operator Results
    ==================================================================
    |        Type of val         |              Result               |
    ==================================================================
    | Undefined                  | "undefined"                       |
    |----------------------------------------------------------------|
    | Null                       | "object"                          |
    |----------------------------------------------------------------|
    | Boolean                    | "boolean"                         |
    |----------------------------------------------------------------|
    | Number                     | "number"                          |
    |----------------------------------------------------------------|
    | String                     | "string"                          |
    |----------------------------------------------------------------|
    | Object (native and does    | "object"                          |
    | not implement [[Call]])    |                                   |
    |----------------------------------------------------------------|
    | Object (native or host and | "function"                        |
    | does implement [[Call]])   |                                   |
    |----------------------------------------------------------------|
    | Object (host and does not  | Implementation-defined except may |
    | implement [[Call]])        | not be "undefined", "boolean",    |
    |                            | "number", or "string".            |
    ------------------------------------------------------------------
    

это поведение в соответствии с стандарт IEEE для арифметики с плавающей запятой (IEEE 754):

количество 4.3.19 стоимостью

примитивное значение, соответствующее 64-разрядному двоичному файлу двойной точности формат IEEE 754 значение

4.3.23 NaN

числовое значение, которое является значением IEEE 754 "Not-a-Number"

8.5 Количество Тип

тип номера имеет ровно 18437736874454810627 (то есть 253-264+3) значения, представляющие собой 64-разрядный формат двойной точности IEEE 754 значения, указанные в стандарте IEEE для двоичной плавающей точки Арифметика, за исключением того, что 9007199254740990 (то есть 253-2) отдельных Значения стандарта IEEE" не-число " представлены в ECMAScript как один специальный Нэн значение. (Обратите внимание, что Нэн значение производится программой expression NaN.)


NaN-допустимое значение с плавающей запятой (http://en.wikipedia.org/wiki/NaN)

и NaN === NaN ложно, потому что они не обязательно одно и то же число


NaN != NaN потому что им не нужно одно и то же число. Таким образом, это имеет большой смысл... Также почему поплавки имеют как +0.00, так и -0.00, которые не совпадают. Округление может сделать так, что они на самом деле не равны нулю.

что касается typeof, это зависит от языка. И большинство языков скажут, что NaN-это float, double или number в зависимости от того, как они его классифицируют... Я не знаю языков, которые скажут, что это неизвестный тип или null.


NaN расшифровывается как не. Это значение числовых типов данных (обычно типов с плавающей запятой, но не всегда), представляющее результат недопустимой операции, такой как деление на ноль.

хотя его имена говорят, что это не число, тип данных, используемый для его хранения, является числовым типом. Итак, в JavaScript, запрашивая тип данных NaN вернутся number (as alert(typeof(NaN)) наглядно демонстрирует).


Javascript использует NaN для представления всего, с чем он сталкивается, что не может быть представлено каким-либо другим способом его спецификациями. Это не значит, что это не число. Это самый простой способ описать встречу. NaN означает, что он или объект, который ссылается на него, не может быть представлен каким-либо другим способом javascript. Для всех практических целей она "неизвестна". Будучи "неизвестным", оно не может сказать вам, что оно такое, и даже если оно само есть. Это даже не тот объект, которому он назначен. Это может только сказать вам, что это не так, и не-ность или ничто может быть описано только математически на языке программирования. Поскольку математика связана с числами, javascript представляет ничто как NaN. Это не значит, что это не номер. Это значит, что мы не можем прочесть это по-другому. Вот почему он не может сравниться с самим собой. Потому что это не так.--1-->


лучшее название для NaN, описывая его значение более точно и менее запутанно, было бы численное исключением. Это действительно другой вид объекта исключения, замаскированный как имеющий примитивный тип (по языковому дизайну), где в то же время он не рассматривается как примитивный в своем ложном само-сравнении. Откуда такая неразбериха? И до тех пор, пока язык "не заставит свой ум" выбирать между правильный объект исключения и примитивный цифра, бестолочь останется.

позорное неравенство NaN для себя и == и === является проявлением запутанного дизайна, заставляющего этот объект исключения быть примитивным типом. Это нарушает фундаментальный принцип, согласно которому примитив однозначно определяется его значением. Если NaN предпочтительнее рассматривать как исключение (из которых могут быть разные виды), тогда оно не должно "продаваться" как примитивное. И если это если хочешь быть примитивным, этот принцип должен соблюдаться. Пока он сломан, как у нас в JavaScript, и мы не можем действительно решить между ними, путаница, приводящая к ненужной когнитивной нагрузке для всех участников, останется. Что, впрочем, очень легко исправить, просто сделав выбор между двумя:

  • либо NaN специальный объект исключения, содержащий полезную информацию о том, как возникло исключение, в отличие от бросания этой информации прочь как то, что в настоящее время реализовано, что приводит к более сложному для отладки коду;
  • или NaN сущность примитивного типа number (это можно было бы менее путано назвать "числовым"), в этом случае он должен быть равен самому себе и не может содержать никакой другой информации; последний явно является подчиненным выбором.

единственное мыслимое преимущество форсирования NaN на number type способен вернуть его в любое числовое выражение. Который, однако делает это хрупкий выбор, потому что результат любого числового выражения, содержащего NaN будет NaN, или приводит к непредсказуемым результатам, таким как NaN < 0 оценка для false, т. е. возвращение boolean вместо сохранения исключения.

и даже если "все так, как есть", ничто не мешает нам сделать это четкое различие для себя, чтобы помочь сделать наш код более предсказуемым и легко отлаживаемым. На практике это означает выявление эти исключения и обращение с ними как с исключениями. Что, к сожалению, означает больше кода, но, надеюсь, будет смягчено такими инструментами, как TypeScript Flowtype.

и тогда у нас есть беспорядок тихий vs шумный ака сигнализация NaN различие. На самом деле речь идет о том, как обрабатываются исключения, а не сами исключения и ничем не отличаются от других исключений.

аналогично, Infinity и +Infinity являются элементы числовой тип возникающие в расширение реальной линии но это не реальные числа. Математически они могут быть представлены последовательностями вещественных чисел, сходящихся к любому + или -Infinity.


Это просто потому, что NaN является свойством объекта Number в JS, оно не имеет ничего общего с тем, что это число.


лучший способ думать о NAN является то, что его не известный количество. Вот почему НЭН != NAN, потому что каждое значение NAN представляет некоторое уникальное неизвестное число. NANs необходимы, потому что числа с плавающей запятой имеют ограниченный диапазон значений. В некоторых случаях округление происходит там, где теряются нижние биты, что приводит к тому, что кажется бессмысленным, как 1.0/11*11 != 1.0. Действительно большие значения, которые больше, - это NANs с бесконечностью, являющейся идеальным примером.

учитывая, что мы только любая попытка показать значения больше 10 невозможна, что означает, что такие значения должны быть NANs, потому что мы потеряли истинное значение этого значения больше 10. То же самое верно для значений с плавающей запятой, где значение превышает пределы того, что может быть удержано в поплавке.


NaN является числом с точки зрения типа, но не является нормальным числом, таким как 1, 2 или 329131. Имя "Не Число" относится к тому факту, что представленное значение является специальным и касается домена спецификации формата IEEE, а не домена языка javascript.


Если вы используете jQuery, я предпочитаю isNumeric проверка типа:

console.log($.isNumeric(NaN));  // returns false
console.log($.type(NaN));       // returns number

http://api.jquery.com/jQuery.isNumeric/


JavaScript имеет только один числовой тип данных, который является стандартным 64-битные двойной точности с плавающей точкой. Все двойное. NaN-это особая ценность double, но тем не менее это double.

все это parseInt does - это "приведение" вашей строки в числовой тип данных, поэтому результат всегда "number"; только если исходная строка не поддается синтаксическому анализу, ее значение будет NaN.


Это специальное значение типа числа как POSITIVE_INFINITY

Почему? По замыслу


NaN по-прежнему является числовым типом, но он представляет значение, которое не может представлять допустимое число.


потому что NaN-это числовой тип данных.


мы могли бы утверждать, что NaN является объектом особого случая. В этом случае объект NaN представляет собой число, которое не имеет математического смысла. В математике есть некоторые другие объекты частного случая, такие как INFINITE и так далее.

вы все еще можете сделать некоторые вычисления с ним, но это даст странное поведение.

дополнительная информация здесь:http://www.concentric.net / ~ttwang/tech/javafloat.htm (на основе java, а не javascript)


вы должны любить Javascript. Он имеет некоторые интересные особенности.

http://wtfjs.com/page/13

большинство этих причуд можно объяснить, если вы остановитесь, чтобы выработать их логически, или если вы немного знаете о теории чисел, но тем не менее они все еще могут поймать вас, если вы не знаете о них.

кстати, я рекомендую прочитать остальную часть http://wtfjs.com/ -- есть гораздо более интересные причуды, чем это один должен быть найден!


значение NaN-это действительно число.Поэтому, когда вы спросите, является ли это число, оно скажет "да". Вы сделали правильную вещь, используя вызов isNaN ().

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