Pergunta

Só por curiosidade.

Não parece muito lógico que typeof NaN é o número.Assim como NaN === NaN ou NaN == NaN retornar false, pelo caminho.Esta é uma das peculiaridades de javascript, ou haverá um motivo para isso?

Editar:obrigado por suas respostas.Não é uma coisa fácil de obter queridos cabeça em redor.Lendo as respostas e o wiki, eu entendi mais, mas ainda assim, uma frase como

Uma comparação com o NaN sempre retorna um desordenada resultado, mesmo quando se compara com o próprio.A comparação predicados são de sinalização ou não de sinalização, sinalização versões sinal de um erro de exceção para esse tipo de comparações.A igualdade e a desigualdade predicados não são de sinalização então x = x retornando false pode ser usado para testar se x é um hotel de NaN.

apenas mantém a minha cabeça girando.Se alguém puder traduzir esta em humanos (em oposição a, digamos, matemático) linguagem legível, gostaria de ser gratefull.

Foi útil?

Solução

Isso significa não um número. Não é uma peculiaridade do JavaScript, mas com o princípio comum da ciência da computação.

A partir de http://en.wikipedia.org/wiki/nan:

Existem três tipos de operação que retornam Nan:

Operações com uma nan como pelo menos um operando

Formas indeterminadas

  • As divisões 0/0, ∞/∞, ∞/−∞, −∞/∞ e −∞/−∞
  • As multiplicações 0 × ∞ e 0 × −∞
  • O poder 1^∞
  • As adições ∞ + (−∞), (−∞) + ∞ e subtrações equivalentes.

Operações reais com resultados complexos:

  • A raiz quadrada de um número negativo
  • O logaritmo de um número negativo
  • A tangente de um múltiplo ímpar de 90 graus (ou π/2 radianos)
  • O seno ou cosseno inverso de um número menor que -1 ou superior a +1.

Todos esses valores podem não ser os mesmos. Um teste simples para uma nan é testar value == value é falso.

Outras dicas

Nós iremos, NaN ainda é um numérico modelo, apesar do fato de realmente não ser um número :-)

NaN significa apenas que o valor específico não pode ser representado dentro das limitações do tipo numérico (embora isso possa ser dito para todos os números que precisam ser arredondados para se encaixar, mas NaN é um caso especial).

Especifico NaN não é considerado igual a outro NaN Porque eles podem ser valores diferentes. No entanto, NaN ainda é um tipo de número, assim como 2718 ou 31415.


Quanto à sua pergunta atualizada para explicar nos termos do leigo:

Uma comparação com uma NAN sempre retorna um resultado não ordenado, mesmo quando se compara consigo mesmo. Os predicados de comparação são sinalizadores ou não-sinalizadores, as versões de sinalização sinalizam uma exceção inválida para essas comparações. Os predicados de igualdade e desigualdade são não-sinalizadores, então x = x retornar false pode ser usado para testar se x for uma nan silenciosa.

Tudo isso significa que é (dividido em partes):

Uma comparação com uma NAN sempre retorna um resultado não ordenado, mesmo quando se compara consigo mesmo.

Basicamente, a NaN não é igual a nenhum outro número, incluindo outro NaN, e mesmo incluindo em si.

Os predicados de comparação são sinalizadores ou não-sinalizadores, as versões de sinalização sinalizam uma exceção inválida para essas comparações.

Tentando fazer comparação (menos que, maior que e assim por diante) as operações entre um NaN E outro número pode resultar em uma exceção sendo lançada (sinalização) ou apenas ficar falsa como resultado (não-sinalização ou silencioso).

Os predicados de igualdade e desigualdade são não-sinalizadores, então x = x retornar false pode ser usado para testar se x for uma nan silenciosa.

Os testes de igualdade (igual a, não iguais a) nunca estão sinalizando, portanto, usá -los não causará uma exceção. Se você tem um número regular x, então x == x sempre será verdade. Se x é um NaN, então x == x sempre será falso. Está lhe dando uma maneira de detectar NaN facilmente (silenciosamente).

O padrão ECMAScript (JavaScript) especifica que Numbers são IEEE 754 carros alegóricos, que incluem NaN como um possível valor.

ECMA 262 5E Seção 4.3.19: Valor do número

Valor primitivo correspondente a um formato binário de precisão dupla de 64 bits IEEE 754 Valor.

ECMA 262 5E Seção 4.3.23: Nan

Valor número que é um valor IEEE 754 "não um número".

IEEE 754 na Wikipedia

O padrão IEEE para aritmética de ponto flutuante é um padrão técnico estabelecido pelo Instituto de Engenheiros de Elétrica e Eletrônica e o padrão mais amplamente utilizado para computação de ponto flutuante [...

O padrão define

  • Formatos aritméticos: Conjuntos de dados de ponto flutuante binário e decimal, que consistem em números finitos (incluindo zeros assinados e números subnormais), infinitos e Valores especiais de "não um número" (NANS)

[...]

typeof NaN retorna 'number' porque:

  • ECMAScript especificação diz o tipo de Número inclui NaN:

    4.3.20 o tipo de Número de

    conjunto de todos os possíveis valores de Número, incluindo o especial "Não é um Número" (NaN) valores infinito, e o infinito negativo

  • Então, typeof retorna assim:

    11.4.3 O Operador typeof

    A produção UnaryExpression : typeof UnaryExpression é avaliado da seguinte forma:

    1. Deixe val ser o resultado da avaliação de UnaryExpression.
    2. Se Tipo(val) é Referência, e , em seguida,
      1. Se IsUnresolvableReference(val) é verdadeiro, retorno "undefined".
      2. Deixe val ser GetValue(val).
    3. Retornar uma Seqüência de caracteres determinados por Tipo(val) de acordo com a Tabela 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".            |
    ------------------------------------------------------------------
    

Este comportamento está de acordo com O Padrão IEEE para a Aritmética de Ponto Flutuante (IEEE 754):

4.3.19 valor de Número de

valor primitivo correspondente a uma precisão dupla de 64 bits binários formato IEEE 754 valor

4.3.23 NaN

o valor do número que é um padrão IEEE 754 "Não é um Número" valor

8.5 O Tipo De Número

O tipo de Número que tem exatamente 18437736874454810627 (isto é, 253−264+3) valores, representando a precisão dupla de 64 bits do formato IEEE 754 valores conforme especificado no Padrão IEEE para Ponto Flutuante Binário Aritmética, exceto que o 9007199254740990 (isto é, 253-2) distintas "Não é um Número" valores do Padrão IEEE são representados em ECMAScript como um único especiais NaN o valor.(Observe que o NaN valor é produzido pelo programa de expressão NaN.)

Nan é um valor de ponto flutuante válido (http://en.wikipedia.org/wiki/nan)

e nan === nan é falso porque não são necessariamente o mesmo número não

NaN != NaN Porque eles não são necessários o mesmo número não-número. Assim, faz muito sentido ... também por que os carros alegóricos têm +0,00 e -0,00 que não são os mesmos. O arredondamento pode fazer isso, na verdade não é zero.

Quanto ao tipo de, isso depende do idioma. E a maioria dos idiomas dirá que a NAN é um flutuador, duplo ou número, dependendo de como o classificam ... Não conheço idiomas que dirão que esse seja um tipo ou nulo desconhecido.

NaN apoia Não um número. É um valor dos tipos de dados numéricos (geralmente tipos de pontos flutuantes, mas nem sempre) que representa o resultado de uma operação inválida, como a divisão por zero.

Embora seus nomes digam que não é um número, o tipo de dados usado para mantê -lo é um tipo numérico. Então, em JavaScript, solicitando o tipo de dados de NaN retornará number (Como alert(typeof(NaN)) demonstra claramente).

O JavaScript usa a NAN para representar qualquer coisa que encontre que não possa ser representada de outra maneira por suas especificações. Isso não significa que não é um número. É apenas a maneira mais fácil de descrever o encontro. NAN significa que ele ou um objeto que se refere a ele não poderia ser representado de outra maneira por JavaScript. Para todos os propósitos práticos, é "desconhecido". Sendo 'desconhecido', não pode lhe dizer o que é nem mesmo que seja. Não é mesmo o objeto ao qual é atribuído. Só pode dizer o que não é, e não-nessa ou nada só pode ser descrito matematicamente em uma linguagem de programação. Como a matemática é sobre números, o JavaScript representa o nada como NAN. Isso não significa que não é um número. Isso significa que não podemos ler de outra maneira que faça sentido. É por isso que não pode nem se igual. Porque não.

Um nome melhor para NaN, descrever seu significado com mais precisão e menos confusa, seria um exceção numérica. É realmente outro tipo de objeto de exceção disfarçado de ter um tipo primitivo (pelo design do idioma), onde, ao mesmo tempo, não é tratado como primitivo em sua falsa auto-comparação. De onde a confusão. E enquanto o idioma "não fará sua mente" escolher entre objeto de exceção adequada e numeral primitivo, a confusão vai ficar.

A infame não igualdade de NaN para si mesmo, ambos == e === é uma manifestação do design confuso, forçando esse objeto de exceção a ser um tipo primitivo. Isso quebra o princípio fundamental de que um primitivo é determinado exclusivamente por seu valor. Se NaN é preferido ser visto como exceção (da qual pode haver tipos diferentes), então não deve ser "vendido" como primitivo. E se for desejado ser primitivo, esse princípio deve se manter. Enquanto estiver quebrado, como temos em JavaScript, e não podemos realmente decidir entre os dois, a confusão que leva à carga cognitiva desnecessária para todos os envolvidos permanecerá. O que, no entanto, é realmente fácil de corrigir simplesmente fazendo a escolha entre os dois:

  • make NaN Um objeto de exceção especial que contém as informações úteis sobre como surgiu a exceção, em vez de eliminar essas informações como o que é implementado atualmente, levando a um código mais difícil de debugão;
  • ou fazer NaN uma entidade do tipo primitivo number (Isso pode ser menos confuso chamado de "numérico"), nesse caso, deve ser igual a si mesmo e não pode conter outras informações; O último é claramente uma escolha inferior.

A única vantagem concebível de forçar NaN em number O tipo é capaz de jogá -lo de volta em qualquer expressão numérica. O que, no entanto, torna a escolha quebradiça, porque o resultado de qualquer expressão numérica contendo NaN será NaN, ou levando a resultados imprevisíveis, como NaN < 0 avaliação de false, ou seja, retornando boolean Em vez de manter a exceção.

E mesmo que "as coisas sejam do jeito que são", nada nos impede de fazer essa distinção clara para nós mesmos, para ajudar a tornar nosso código mais previsível e mais fácil degível. Na prática, isso significa identificar essas exceções e lidar com elas como exceções. O que, infelizmente, significa mais código, mas espero que seja mitigado por ferramentas como o TypeScript do Flowtype.

E então temos a bagunça Quiet vs barulhento aka sinalizando NaN distinção. O que é realmente sobre como as exceções são tratadas, não as próprias exceções e nada diferente de outras exceções.

De forma similar, Infinity e +Infinity são elementos de tipo numérico surgindo no extensão da linha real Mas eles não são números reais. Matematicamente, eles podem ser representados por sequências de números reais convergindo para qualquer + ou -Infinity.

Isso é simplesmente porque NaN é uma propriedade do objeto numérico em JS, ele não tem nada a ver com o número de um número.

A melhor maneira de pensar em Nan é que não é um conhecido número. É por isso que nan! = NAN, porque cada valor da NAN representa algum número desconhecido único. Os NANs são necessários porque os números de ponto flutuante têm uma faixa limitada de valores. Em alguns casos, ocorre o arredondamento onde os bits inferiores são perdidos, o que leva ao que parece ser um absurdo como 1,0/11*11! = 1,0. Valores realmente grandes que são maiores são Nans, com o Infinity sendo um exemplo perfeito.

Dado que temos apenas dez dedos, qualquer tentativa de mostrar valores maiores que 10 são impossíveis, o que significa que esses valores devem ser NANs, porque perdemos o valor verdadeiro desse valor maior que 10. O mesmo se aplica aos valores de ponto flutuante, onde o valor excede os limites do que pode ser mantido em um float.

Porque a NAN é um tipo de dados numérico.

NaN é um número de um ponto de vista do tipo, mas não é um número normal como 1, 2 ou 329131. O nome "Não é um número" refere -se ao fato de que o valor representado é especial e é sobre o domínio do IEEE Format Spec, não o domínio da linguagem JavaScript.

Se estiver usando jQuery, eu prefiro isNumeric sobre verificar o tipo:

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

http://api.jquery.com/jquery.isnumeric/

O JavaScript possui apenas um tipo de dados numérico, que é o float padrão de precisão dupla de 64 bits. Tudo é duplo. Nan é um valor especial do dobro, mas é um duplo.

Tudo isso parseInt faz é "lançar" sua string em um tipo de dados numérico, então o resultado é sempre "número"; Somente se a string original não foi parsesível, seu valor será NAN.

A NAN ainda é um tipo numérico, mas representa um valor que não pode representar um número válido.

Poderíamos argumentar que a NAN é um objeto de caso especial. Nesse caso, o objeto de Nan representa um número que não faz sentido matemático. Existem outros objetos de casos especiais em matemática, como infinitos e assim por diante.

Você ainda pode fazer alguns cálculos com ele, mas isso produzirá comportamentos estranhos.

Mais informações aqui: http://www.concentric.net/~ttwang/tech/javafloat.htm (baseado em java, não javascript)

Você tem que amar JavaScript. Tem algumas pequenas peculiaridades interessantes.

http://wtfjs.com/page/13

A maioria dessas peculiaridades pode ser explicada se você parar para resolvê -las logicamente, ou se você souber um pouco sobre a teoria dos números, mas eles ainda poderão vê -lo se você não souber sobre eles.

A propósito, eu recomendo ler o resto de http://wtfjs.com/ - Há muito mais peculiaridades interessantes do que esta a ser encontrada!

O valor nan é realmente o número. Você fez a coisa correta usando a chamada isnan ().

Para obter informações, a NAN também pode ser devolvida por operações em números que não são definidos como divisões por zero ou raiz quadrada de um número negativo.

Um exemplo

Imagine que estamos convertendo uma string em um número:

Number("string"); // returns NaN

Alteramos o tipo de dados para número, mas seu valor não é um número!

É um valor especial do tipo de número como positivo_infinity

Por quê? Por design

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top