JavaScript에서 NaN 값은 내부적으로 광범위한 64 비트 이중으로 표시 될 수 있습니다. 특히 다음과 같은 비트 표현을 가진 모든 double :
x111 1111 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
NaN으로 해석됩니다. 내 질문은 : ArrayBuffers를 사용하여 두 개의 32 비트 uint를 JS 숫자로 캐스트하고 그것을 전달 한 다음 두 개의 32 비트 uint로 캐스트한다고 가정하십시오. 복구 된 비트는 원본과 동일합니까, 아니면 JS 엔진이 NaN의 비트를 마음대로 변경할 수 있습니까? 다시 말해, JS 숫자를 사용하여 64 비트 손실을 저장할 수 있습니까?
답변
ECMA-262 9 번째 에디션 6 월 2018 (표준이되는 자바 스크립트는 의도가 일치하기는) 6.1.6는 “번호 유형”에서 말한다 :
… IEEE 표준 의 9007199254740990 (즉, 2 53 -2) 고유의 “Not-a-Number”값은 ECMAScript에서 단일 특수 NaN 값으로 표시됩니다.… 일부 구현에서 외부 코드는 차이를 감지 할 수 있습니다. 다양한 Not-a-Number 값 사이에서 이러한 동작은 구현에 따라 다릅니다. ECMAScript 코드에서 모든 NaN 값은 서로 구별 할 수 없습니다.
24.1.17“NumberToRawBytes (유형, 값, isLittleEndian)”는 다음과 같이 말합니다.
… 값이 NaN 인 경우 rawBytes는 IEEE 754-2008 binary64 형식 Not-a-Number 인코딩에서 선택한 모든 구현으로 설정할 수 있습니다. 구현은 항상 구현 가능한 식별 가능한 NaN 값마다 동일한 인코딩을 선택해야합니다.…
나는이 질문에 대해 밝히고있는 NaN을 언급하는 다른 구절들을 보지 못했다. 한편으로 24.1.17은 NaN을 원시 바이트로 변환 할 때 NaN의 비트가 보존되어야 함을 효과적으로 알려줍니다. 그러나 다른 작업에서 비트를 유지해야한다고 알려주는 것은 없습니다. 24.1.17의이 요구 사항은 다른 연산에 의해 비트가 임의로 변경 될 수 있다면 목적을 달성하지 못하기 때문에 이것이 의도 인 것으로 추론 할 수있다. 그러나 나는 그 의도에 따라 이것을 구현하기 위해 JavaScript 구현에 의존하지 않을 것입니다.
답변
한때 Java에 대해 NaN 값의 하드웨어 의존성에 대한 질문 을했으며 NaN 값이로드 될 때 일부 CPU에서 “Signaling NaN”을 “quiet NaN”(조용한 NaN 비트 설정)으로 자동 변환하는 것으로 나타났습니다 프로세서 레지스터로. 따라서 조용한 NaN 비트 중 하나 이상의 비트는 임의의 데이터를 저장하는 데 사용할 수 없습니다.
다른 비트를 사용하여, 너무 오래 NaN이 비트가 설정 조용한로,이다 아마 안전합니다. 그러나 여전히 구현 의존성에 대한 여지가있는 것처럼 보이므로 보장 할 수 없습니다.
이런 종류의 문제는 일반적인 언어 운영이 NaN의 내부 가치에 의존하는 것을하지 않고 모든 NaN을 “그냥 NaN”으로 취급하는 것을 선호하는 이유입니다.
답변
원래의 IEEE-754 표준은 의도적으로 NaN 비트를 구현에 맡겼습니다. 다음과 같은 힌트를 제공했습니다.
NaN이 작성된 원래 메모리 주소를 넣을 수 있습니다.
한편, 산술은 NaN으로 무엇을해야하는지에 대한 구체적인 규칙을 가지고 있으며, 이는 바닥의 비트와는 아무런 관련이 없습니다. 나는 두 개의 NaN을 추가 할 때 무엇을 해야할지조차 생각하지 않습니다. 비트 중 하나에서 비트를 유지하고 다른 비트 세트를 구성하십시오. 결과는 여전히 NaN이어야합니다.