typeof NaN이 왜 'number'를 반환합니까?


166

그냥 호기심.

typeof NaN숫자 인 것은 논리적이지 않습니다 . 그건 그렇고 마찬가지로 거짓을 반환 NaN === NaN하거나 NaN == NaN반환합니다. 이것이 자바 스크립트의 특징 중 하나입니까, 아니면 그 이유가 있습니까?

편집 : 답변 주셔서 감사합니다. 그래도 사람들을 이끄는 것은 쉬운 일이 아닙니다. 답을 읽고 위키를 더 이해했지만 여전히 다음과 같은 문장

NaN과의 비교는 자체와 비교할 때도 항상 정렬되지 않은 결과를 반환합니다. 비교 술어는 시그널링 또는 비 시그널링이며, 시그널링 버전은 이러한 비교에 대해 유효하지 않은 예외를 신호합니다. 항등 및 부등식 술어는 신호가 없으므로 x = x false 반환은 x가 조용한 NaN인지 테스트하는 데 사용할 수 있습니다.

그냥 내 머리를 계속 돌립니다. 누군가가 (수학자와는 달리) 인간이 읽을 수있는 언어로 이것을 번역 할 수 있다면, 나는 감사 할 것이다.


17
+1 : "NaN은 숫자이지만 숫자가 아닙니다. 흠 ... 뭐?!"
ereOn

11
추가 재미를 위해; (NaN! == NaN) == true
Alex K.

1
더 재미있다 (그러나 이해하기 쉽게 isNaN은 부울을 반환합니다) : isNaN (parseInt ( 'nodice')) === isNaN (parseInt ( 'someOtherNaN')) === true;
KooiInc

1
jQuery를 사용하는 isNumeric경우 유형을 확인하는 것을 선호 $.isNumeric(NaN); 합니다. false를 $.type(NaN);반환합니다. 여기서 as 는 숫자를 반환합니다. api.jquery.com/jQuery.isNumeric
저스틴

3
전문 수학자로서 나는 문장이 정확한 수학 언어와 공통점이 거의 없다고 말해야합니다.
Dmitri Zaitsev

답변:


53

숫자가 아님을 의미합니다. 자바 스크립트의 특성은 아니지만 일반적인 컴퓨터 과학 원리입니다.

에서 http://en.wikipedia.org/wiki/NaN :

NaN을 반환하는 세 가지 종류의 작업이 있습니다.

하나 이상의 피연산자로 NaN을 사용하는 연산

불확실한 형태

  • 0/0, ∞ / ∞, ∞ / −∞, −∞ / ∞ 및 −∞ / −∞ 나누기
  • 곱셈 0 × ∞ 및 0 × −∞
  • 힘 1 ^ ∞
  • 더하기 ∞ + (−∞), (−∞) + ∞ 및 동등한 빼기.

복잡한 결과를 가진 실제 작업 :

  • 음수의 제곱근
  • 음수의 로그
  • 90 도의 홀수 배수의 접선 (또는 π / 2 라디안)
  • -1보다 작거나 +1보다 큰 숫자의 역 사인 또는 코사인.

이 모든 값이 같지 않을 수 있습니다. NaN에 대한 간단한 테스트는 테스트하는 것 value == value입니다.


46
더 간단한 테스트는 다음과 같습니다isNaN(value)
Alsciende

4
@Alsciende 그것은 동일하지 않습니다. isNaN(undefined)를 반환 true하지만 undefined == undefined사실이기도합니다. 를 제외한 다른 모든 비 숫자 유형에도 동일하게 적용 null됩니다.
Andy

7
다른 말로하면, value !== value아마도 true value인지 테스트하는 가장 짧은 방법 일 것입니다 NaN.
Andy

1
당신이 옳은 것 같습니다, @ 앤디. 이제는 특이합니다.
Alsciende

2
"이러한 값이 같지 않을 수 있습니다"라는 문구는 의미가 없습니다. 해당 값이 없기 때문입니다.
Dmitri Zaitsev

103

글쎄, 그것은 실제로 NaN숫자 가 아닙니다 :-)에도 불구하고 여전히 숫자 유형입니다 .

NaN단지 숫자 값의 한계 내에서 특정 값을 표현할 수 없다는 것을 의미합니다 (반올림 해야하는 모든 숫자에 대해 말할 수는 있지만 NaN특별한 경우입니다).

특정 값은 다른 값일 수 있으므로 다른 값 NaN과 동일하게 간주되지 않습니다 NaN. 그러나 NaN2718 또는 31415와 같이 여전히 숫자 유형입니다.


평신도의 용어로 설명하기 위해 업데이트 된 질문에 관해서 :

NaN과의 비교는 자체와 비교할 때도 항상 정렬되지 않은 결과를 반환합니다. 비교 술어는 시그널링 또는 비 시그널링이며, 시그널링 버전은 이러한 비교에 대해 유효하지 않은 예외를 신호합니다. 항등 및 부등식 술어는 신호가 없으므로 x = x는 false를 반환하여 x가 조용한 NaN인지 테스트하는 데 사용할 수 있습니다.

이 모든 것은 (부분으로 나뉘어 있음)입니다.

NaN과의 비교는 자체와 비교할 때도 항상 정렬되지 않은 결과를 반환합니다.

기본적으로 a NaN는 다른를 포함하여 다른 숫자와 같지 않으며 NaN심지어는 자신을 포함 합니다. .

비교 술어는 시그널링 또는 비 시그널링이며, 시그널링 버전은 이러한 비교에 대해 유효하지 않은 예외를 신호합니다.

사이의 비교 (보다 작거나 크거나 등) 작업을 시도 NaN숫자와 다른 숫자 하면 예외가 발생하거나 (신호 발생) 결과로 거짓이 될 수 있습니다 (신호가 발생하지 않거나 조용함).

항등 및 부등식 술어는 신호가 없으므로 x = x는 false를 반환하여 x가 조용한 NaN인지 테스트하는 데 사용할 수 있습니다.

동등성 (같거나 같지 않음)에 대한 테스트는 신호를 보내지 않으므로이를 사용하면 예외가 발생하지 않습니다. 정기적 번호가있는 경우 x, 다음 x == x항상 true가됩니다. 경우 xNaN다음 x == x항상 false가 될 것입니다. NaN쉽게 (조용하게) 감지하는 방법을 제공합니다 .


1
마지막 두 문장에 동의하지 않더라도 좋은 설명 : x가 NaN인지 확인하는 더 좋은 방법은 isNaN () 함수를 사용하는 것입니다
Carlos Barcelona

@DominicRodger 여기에 내가 어떻게 생각하는지 : typeof a === 'number'"a는 내부적으로 IEEE 754 float로 저장된다"는 의미
Andy

1.0 / 0.0 또는 2.0 / 0.0의 다른 값으로 생산할 수 있다면 왜 Infinity === Infinity반환 합니까? trueInfinity
Hashem Qolami

1
@Hashem, 그들은 같은 무한대로 간주되기 때문에 가능성이 높습니다. 반복 빼기로 분할 치료, 당신이 두 하나, 그것은 범위 (또는, 더 정확하게에 필요한 단계의 같은 수의 시작 여부를 차이도하지 않습니다 하지 도달) 제로. 나는 수학 전문가 들이 서로 다른 종류의 무한대를 가지고 있다는 것을 이해 하지만 (1) 같은 클래스에 있다고 생각 1/0하고 2/0누워 +/-있습니다.
paxdiablo

1
의미있는 방식으로 이러한 "실제 숫자"를 정의 할 수있는 방법을 모릅니다. 수학에서 로그와 음의 근은 실수를 복소수로 확장하여 얻을 수 있으며 여러 값으로 평가되며 0/0"값"이 전체 세트라고 말하는 것 외에는 의미있는 방식으로 정의되지 않습니다. 숫자. 그리고 정의 된 경우 Math.log(-1) == Math.log(-1)에도 여전히로 평가됩니다 false. 따라서 "실제 숫자"외에 다른 것이 NaN있을뿐 아니라 비교에도 사용되지 않았습니다.
Dmitri Zaitsev

20

ECMA 스크립트 (JavaScript)를 표준 지정 Numbers되어 IEEE 754 등 수레 NaN가능한 값.

ECMA 262 5e Section 4.3.19 : 숫자 값

배정도 64 비트 이진 형식 IEEE 754 값에 해당하는 기본 값.

ECMA 262 5e 섹션 4.3.23 : NaN

IEEE 754 "Not-a-Number"값인 숫자 값입니다.

Wikipedia의 IEEE 754

부동 소수점 산술에 대한 IEEE 표준은 전기 전자 학회 (Institute of Electrical and Electronics Engineers)에 의해 확립 된 기술 표준이며 부동 소수점 계산에 가장 널리 사용되는 표준입니다 ...]

표준은

  • 산술 형식 : 유한 숫자 (부호있는 0 및 하위 정규수 포함), 무한대 및 특수한 숫자가 아닌 값 (NaN)으로 구성된 이진 및 십진 부동 소수점 데이터 세트

[...]


8

typeof NaN다음과 같은 'number'이유로 반환됩니다 .

  • ECMAScript 사양에 따르면 숫자 유형에 NaN이 포함되어 있습니다.

    4.3.20 숫자 유형

    특수 "NaN (Not-a-Number)"값, 양의 무한대 및 음의 무한대를 포함하여 가능한 모든 숫자 값 세트

  • 따라서 typeof그에 따라 반환됩니다.

    11.4.3 연산자의 유형

    UnaryExpression : typeof UnaryExpression 프로덕션 은 다음과 같이 평가됩니다.

    1. 하자 발은 평가의 결과 UnaryExpression을 .
    2. 경우 유형 ( 발은 )는 참조 후,
      1. 경우 IsUnresolvableReference ( 발은 )는 사실 , 반환 "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 (즉, 2 53 -2 64 +3) 값을 가지며, 9007199254740990 (이진 부동 소수점 산술에 대한 IEEE 표준에 지정된 배정도 64 비트 형식 IEEE 754 값을 나타냄) 즉, IEEE 표준의 2 53 -2) 고유 한 "Not-a-Number"값은 단일 특수 NaN 값 으로 ECMAScript에 표시됩니다 . (점을 유의 하는 NaN 값은 프로그램의 발현에 의해 생성된다 NaN.)


5

NaN은 유효한 부동 소수점 값입니다 ( http://en.wikipedia.org/wiki/NaN )

NaN === NaN은 반드시 숫자가 아닌 동일한 것이 아니기 때문에 false입니다.


1
미안하지만 나는 그것을 생각하는 좋은 방법이 아니라고 말해야합니다. "동일하지 않은 숫자"가 항상 다르다는 것을 의미하지는 않으며 그것들을 비교하면 거짓이되어야합니다. NaN을 정량화하지 않고 지식 기반에서 이상하다고 생각하는 것이 가장 좋습니다.
Dave

1
그렇다면 왜 모든 Infinity것이 동일합니까? 이견있는 사람?
Hashem Qolami

5

NaN != NaN동일한 숫자가 아닌 필요하지 않기 때문입니다. 따라서 많은 의미가 있습니다 ... 또한 왜 floats가 +0.00과 -0.00을 모두 같지 않은지 알 수 있습니다. 반올림은 실제로 0이 아닌 것을 할 수 있습니다.

typeof는 언어에 따라 다릅니다. 그리고 대부분의 언어는 NaN이 분류 방법에 따라 float, double 또는 number라고 말합니다. 나는 이것이 알 수없는 유형이거나 널이라고 말할 언어가 없습니다.


1
ehr, 고려 : var x = parseInt ( 'no dice'), y = x; 이제 두 NaN이 정확히 같다고 말할 수 있습니까? 그러나 아니요, x === y도 false를 반환합니다.
KooiInc

예, 그러나 당신은 확실하지 않으므로 동일하지 않습니다. 데이터베이스의 NULL 가능 논리와 동일한 논리입니다. 많은 사람들이 다른 프로그래밍 언어의 널 포인터와 동일하다고 생각하지만 실제로는 완전히 다른 의미를 갖습니다. "UNKNOWN"이므로 다른 NULL 값에 비해 하나의 NULL 값은 항상 false입니다. NULL 값을 계산하면 결과 NULL이됩니다. 대신 UNKNOWN이라는 가치의 관점에서 보도록하십시오
Cine

유형 numberNaN이므로 원시적이므로 값에 따라 고유하게 결정됩니다.
Dmitri Zaitsev

4

NaN숫자 아님을 나타냅니다 . 0으로 나누는 것과 같은 유효하지 않은 연산의 결과를 나타내는 숫자 데이터 유형 (일반적으로 부동 소수점 유형이지만 항상 그런 것은 아님)의 값입니다.

이름이 숫자가 아니라고 말하지만 데이터를 보유하는 데 사용되는 데이터 유형은 숫자 유형입니다. 따라서 JavaScript에서의 데이터 유형을 요구 NaN하면 number(반드시 alert(typeof(NaN))보여 주듯이) 리턴 됩니다 .


실제로 0으로 나누어은로 평가 Infinity하지NaN
드미트리 Zaitsev

2

Javascript는 NaN을 사용하여 사양으로 다른 방법으로는 표현할 수없는 모든 것을 나타냅니다. 숫자가 아님을 의미하지는 않습니다. 만남을 설명하는 가장 쉬운 방법입니다. NaN은 해당 객체 또는이를 참조하는 객체를 다른 방법으로 javascript로 표현할 수 없음을 의미합니다. 모든 실제적인 목적으로 '알 수 없음'입니다. '알 수 없음'이기 때문에 그것이 무엇인지, 심지어 그 자체인지는 알 수 없습니다. 심지어 할당 된 개체가 아닙니다. 그것은 당신에게 그것이 아닌 것이 무엇인지 말해 줄 수 있으며, 그렇지 않은 것은 아무것도 프로그래밍 언어로만 수학적으로 기술 될 수 있습니다. 수학은 숫자에 관한 것이기 때문에, 자바 스크립트는 아무것도 없음을 NaN으로 나타냅니다. 그렇다고 숫자가 아니라는 의미는 아닙니다. 그것은 우리가 이해하는 다른 방법으로는 읽을 수 없다는 것을 의미합니다. 그것이 가능한 이유입니다 ' 그 자체도 같지 않습니다. 그렇지 않기 때문에.


2

NaN그 의미를보다 정확하고 덜 혼란스럽게 묘사 하는 더 좋은 이름 은 수치 예외 입니다. 그것은 (언어 디자인에 의해) 기본 유형을 갖는 것으로 위장한 또 다른 종류의 예외 객체입니다. 혼란이 생겼을 때. 언어가 적절한 예외 객체프리미티브 숫자 중 하나를 선택하기 위해 "마음에 들지 않을 것"이라면 혼란은 계속 될 것입니다.

NaN자체 의 악명 높은 비평 =====은이 예외 객체를 원시 유형으로 만드는 혼란스러운 디자인의 표현입니다. 이것은 프리미티브가 그 가치에 의해 유일하게 결정 된다는 기본 원칙을 위반합니다 . NaN예외로 여겨지는 것이 바람직한 경우 (다른 종류가있을 수 있음), 기본으로 "판매"해서는 안됩니다. 그리고 그것이 원시적이기를 원한다면, 그 원칙이 반드시 지켜 져야합니다. 우리가 JavaScript에서와 같이 그것이 깨져서 실제로 두 가지를 결정할 수 없다면, 관련된 모든 사람들에게 불필요한인지 부하로 이어지는 혼란이 남아있을 것입니다. 그러나 둘 중 하나만 선택하면 쉽게 고칠 수 있습니다.

  • NaN현재 구현 된 정보를 버리는 것과 달리 예외가 발생하는 방법에 대한 유용한 정보를 포함하는 특수한 예외 객체를 만들어 디버그하기 어려운 코드를 만듭니다.
  • 또는 NaN원시적 유형의 엔티티 number(혼동하기 쉽지 않은 "숫자")를 작성하십시오.이 경우 자체와 동일해야하며 다른 정보를 포함 할 수 없습니다. 후자는 분명히 열등한 선택입니다.

유형 을 강요 NaN할 때 유일하게 생각할 수있는 장점은 number숫자 식으로 되돌릴 수 있다는 것입니다. 어떤, 그러나 부서지기 쉬운 선택을하게, 어떤 숫자 식의 결과가 들어 있기 때문에 NaN이 될 것입니다 NaN, 또는 같은 예상치 못한 결과로 이어지는 NaN < 0로 평가 false즉, 반환 boolean하는 대신 예외를 유지.

"사물이있는 그대로"라도 코드를보다 예측 가능하고 쉽게 디버깅 할 수 있도록 자신을 명확하게 구분할 수있는 것은 없습니다. 실제로 이는 예외를 식별하고 예외로 처리하는 것을 의미합니다. 불행히도, 더 많은 코드를 의미하지만 Flowtype의 TypeScript와 같은 도구로 완화되기를 바랍니다.

그리고 우리는 지저분한 조용한 대 시끄러운 일명 신호 NaN구별이 있습니다. 실제로 예외 자체가 아니라 예외를 처리하는 방법에 관한 것이며 다른 예외와 다른 점은 없습니다.

이와 유사하게, Infinity그리고 +Infinity의 요소 숫자 형식 에서 발생하는 실제 라인의 확장은 그러나 그들은 실수하지 않습니다. 수학적으로 이들은 +또는로 수렴하는 실수 시퀀스로 표현 될 수 있습니다 -Infinity.


1

이것은 NaNJS에서 Number 객체의 속성 이기 때문에 단순히 숫자와 관련이 없습니다.


다른 모든 객체와 마찬가지로 Number는 모든 유형의 속성을 가질 수 있습니다. Number.fu = "bar"; alert(typeof Number.fu);
Alsciende

NaN에 저장된 값이 아닙니다 Number.NaN. NaN숫자 유형의 기본 값입니다. 또한 Number.NaNis 의 값은 NaN관련이 없습니다.
Oriol

1

NAN을 생각하는 가장 좋은 방법은 알려진 숫자 가 아니라는 것입니다 . 각 NAN 값이 고유 한 알 수없는 숫자를 나타내므로 NAN! = NAN 인 이유는 무엇입니까? 부동 소수점 숫자의 값 범위가 제한되어 있으므로 NAN이 필요합니다. 어떤 경우에는 하위 비트가 손실되는 반올림이 발생하여 1.0 / 11 * 11! = 1.0과 같이 넌센스로 나타납니다. 실제로 더 큰 값은 무한대가 완벽한 예인 NAN입니다.

손가락이 10 개 밖에없는 경우 10보다 큰 값을 표시하려는 시도는 불가능합니다. 즉, 10보다 큰이 값의 실제 값을 잃었으므로 이러한 값은 NAN이어야합니다. 부동 소수점 값의 경우도 마찬가지입니다. 여기서 값은 부동 소수점에 보유 할 수있는 한계를 초과합니다.


무한대는 NaN으로 표시되지 않습니다. 범위를 벗어난 숫자를 나타내려고하면 반올림되거나 (최대 / inf로) 또는 위로 (분 / + inf로) 반올림됩니다.
OrangeDog

1

NaN은 숫자 데이터 유형이므로


1

NaN유형 관점의 숫자이지만 1, 2 또는 329131과 같은 일반 숫자는 아닙니다. "숫자 아님" 이라는 이름 은 표시된 값이 특별하고 IEEE 형식 사양 도메인에 관한 것이 아니라는 사실을 나타냅니다. 자바 스크립트 언어 도메인.


1

jQuery를 사용하는 isNumeric경우 유형을 확인하는 것을 선호 합니다.

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

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


고마워요 Typescript 패키지 isNumber에서 문제가 발생했습니다 util. 우리는 여전히 jQuery프로젝트에서 사용 하므로 제안을 대신 사용했습니다.
Ashok MA

rec의 경우 isNumberfrom utilof typescript도를 반환 true합니다 NaN.
Ashok MA

0

Javascript에는 하나의 숫자 데이터 유형 만 있으며 표준 64 비트 배정 밀도 부동 소수점입니다. 모든 것이 두 배입니다. NaN은 double의 특별한 값이지만 그럼에도 불구하고 double입니다.

이 모든 parseInt결과가 그렇게는 숫자 데이터 타입으로 당신의 문자열 "캐스트"이다 항상 "수"; 원래 문자열을 구문 분석 할 수없는 경우에만 값이 NaN이됩니다.


0

NaN은 여전히 ​​숫자 유형이지만 유효한 숫자를 나타낼 수없는 값을 나타냅니다.


0

NaN은 특수한 경우라고 주장 할 수 있습니다. 이 경우 NaN의 객체는 수학적으로 의미가없는 숫자를 나타냅니다. INFINITE와 같은 수학에는 다른 특별한 경우 객체가 있습니다.

여전히 일부 계산을 수행 할 수는 있지만 이상한 동작이 발생합니다.

더 많은 정보는 여기에 있습니다 : http://www.concentric.net/~ttwang/tech/javafloat.htm (자바 스크립트가 아닌 자바 기반)


0

당신은 자바 스크립트를 좋아해야합니다. 흥미로운 작은 특징이 있습니다.

http://wtfjs.com/page/13

논리적으로 문제를 해결하지 않거나 숫자 이론에 대해 조금만 알고 있다면 이러한 단점은 대부분 설명 할 수 있지만 그럼에도 불구하고 그것들을 모른다면 여전히 당신을 따라 잡을 수 있습니다.

그건 그렇고, 나는 http://wtfjs.com/ 의 나머지 부분을 읽는 것이 좋습니다. 이보다 더 흥미로운 단점이 있습니다!


0

NaN 값은 실제로 Number입니다 .NaN 따라서 숫자인지 물으면 예라고 말합니다. isNaN () 호출을 사용하여 올바른 작업을 수행했습니다.

정보를 위해 음수의 제로 또는 제곱근으로 나누기와 같이 정의되지 않은 숫자에 대한 연산으로 NaN을 반환 할 수도 있습니다.


어떤 의미에서 "가치"는 무엇입니까? NaN == Number.NaN로 평가 false!
Dmitri Zaitsev

@DmitriZaitsev 스레드를 읽었습니까? 그리고 (parseInt ( "nan") == Number.NaN)을 시도 했습니까? 또한! = 시도하고 그것이 무엇을 말하는지보십시오.
Rob

죄송합니다, 멍청한 NaN==NaN존재를 잊어 버렸습니다 false. 모두가 고통을 느끼도록 발명 한 것은 슬픈 일 이었을 것입니다.
Dmitri Zaitsev

0

문자열을 숫자로 변환한다고 상상해보십시오.

Number("string"); // returns NaN

데이터 유형을 숫자로 변경했지만 값이 숫자가 아닙니다!


당신은 질문의 요점을 놓친 것 같습니다. NaN의 인 수의 유형입니다. 문제는 이유를 묻는 것입니다.
Quentin

@Quentin 마지막 줄에서 설명했습니다.
Amir Fo

-1

POSITIVE_INFINITY로서 숫자 형의 특별한 값

왜? 디자인에 의해

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.