Em JavaScript, o valor NaN pode ser representado por uma ampla variedade de dobras de 64 bits internamente. Especificamente, qualquer duplo com a seguinte representação bit a bit:
x111 1111 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
É interpretado como um NaN. Minha pergunta é: suponha que eu conjure duas uints de 32 bits em um número JS usando ArrayBuffers, passe-as e depois as converta novamente em duas uints de 32 bits. Os bits recuperados serão iguais aos originais, ou os mecanismos JS podem alterar os bits de um NaN à vontade? Em outras palavras, os números JS podem ser usados para armazenar perdas de 64 bits?
javascript
ieee-754
MaiaVictor
fonte
fonte
Respostas:
ECMA-262 9 ª Edição, Junho de 2018, (o padrão ao qual se destina o JavaScript para conformar) diz, em 6.1.6 “o tipo de número”:
24.1.17 "NumberToRawBytes (tipo, valor, isLittleEndian)" diz:
Não vejo nenhuma outra passagem que mencione NaN que esteja esclarecendo essa questão. Por um lado, 24.1.17 nos diz efetivamente que os bits de um NaN devem ser preservados ao converter o NaN em bytes brutos. No entanto, nada mais parece nos dizer que os bits devem ser preservados em outras operações. Pode-se deduzir que essa é a intenção, porque esse requisito em 24.1.17 não serviria para nada se os bits pudessem ser arbitrariamente alterados por qualquer outra operação. Mas eu não confiaria nas implementações de JavaScript para implementá-las em conformidade com essa intenção.
fonte
Certa vez, fiz uma pergunta para Java sobre a dependência de hardware dos valores de NaN, e percebemos que algumas CPUs convertem silenciosamente um "NaN de sinalização" em um "NaN silencioso" (configurando o bit silencioso de NaN) quando um valor NaN é carregado em um registro do processador. Portanto, pelo menos um dos bits, o silencioso NaN, você não pode usar para armazenar dados arbitrários.
Usar os outros bits, desde que o bit NaN silencioso esteja definido, provavelmente é seguro. Mas ainda parece haver espaço para dependência de implementação aqui e, portanto, nenhuma garantia.
Esse tipo de problema é o motivo pelo qual as operações normais de linguagem evitam fazer qualquer coisa que dependa do valor interno de um NaN e preferem tratar todos os NaNs como "apenas NaN".
fonte
O padrão IEEE-754 original deixou deliberadamente os bits de um NaN até a implementação. Ele forneceu dicas, como
Você pode colocar o endereço de memória original de onde o NaN foi criado.
Enquanto isso, a aritmética tem regras específicas sobre o que fazer com um NaN, e isso não tem nada a ver com os bits no fundo. Eu acho que nem diz o que fazer ao adicionar dois NaNs - mantenha os bits de um deles em vez de criar outro conjunto de bits. Só que o resultado ainda deve ser um NaN.
fonte