Eu gostaria de ver números inteiros, positivos ou negativos, em binário.
Um pouco como esta pergunta , mas para JavaScript.
javascript
numbers
barlop
fonte
fonte
Respostas:
Você pode usar a
Number.toString(2)
função, mas há alguns problemas ao representar números negativos. Por exemplo, a(-1).toString(2)
saída é"-1"
.Para corrigir esse problema, você pode usar o operador bit a bit de deslocamento à direita não assinado (
>>>
) para coagir seu número a um número inteiro não assinado.Se você executar,
(-1 >>> 0).toString(2)
você deslocará seu número 0 bits para a direita, o que não altera o número em si, mas será representado como um número inteiro não assinado. O código acima será exibido"11111111111111111111111111111111"
corretamente.Esta pergunta tem mais explicações.
fonte
Experimentar
O 2 é a raiz e pode ser qualquer base entre 2 e 36
fonte aqui
ATUALIZAR:
Isso funcionará apenas para números positivos. Javascript representa números inteiros binários negativos na notação complemento de dois. Eu criei essa pequena função que deve funcionar, não a testei corretamente:
Eu tive alguma ajuda daqui
fonte
-3
retornos1
). Também acredito quedec > 0
deveria serdec >= 0
, que deveria pelo menos consertar 0. Porquedec2Bin(0)
retorna10
.O binário em 'converter em binário' pode se referir a três coisas principais. O sistema numérico posicional, a representação binária na memória ou as cadeias de bits de 32 bits. (para bits de 64 bits, veja a resposta de Patrick Roberts )
1. Sistema Numérico
(123456).toString(2)
irá converter números para o sistema numérico posicional de base 2 . Neste sistema, os números negativos são escritos com sinais de menos, como em decimal.2. Representação Interna
A representação interna dos números é ponto flutuante de 64 bits e algumas limitações são discutidas nesta resposta . Não existe uma maneira fácil de criar uma representação disso em javascript nem acessar bits específicos.
3. Máscaras e operadores bit a bit
O MDN tem uma boa visão geral de como os operadores bit a bit funcionam. Importante:
Antes da aplicação das operações, os números de pontos flutuantes de 64 bits são convertidos em números inteiros assinados de 32 bits. Depois que eles são convertidos de volta.
Aqui está o código de exemplo MDN para converter números em cadeias de 32 bits.
fonte
Uma maneira simples é apenas ...
fonte
(42).toString(2)
42..toString(2)
1.
que é igual1.0
ou apenas1
(e da mesma forma também pode omitir a parte anterior e escrever em.5
vez de0.5
). Portanto, no exemplo, o primeiro ponto é o separador decimal que faz parte do número e o segundo ponto é o operador de ponto para chamar o método nesse número. Você precisa usar dois pontos (ou colocar o número entre parênteses) e não pode escrever apenas42.toString(2)
porque o analisador vê o ponto como separador decimal e gera um erro devido a um operador de ponto ausente.Esta resposta tenta endereçar entradas com um valor absoluto no intervalo de 2147483648 10 (2 31 ) - 9007199254740991 10 (2 53 -1).
No JavaScript, os números são armazenados na representação de ponto flutuante de 64 bits , mas as operações bit a bit os coagem para números inteiros de 32 bits no formato de complemento de dois , portanto, qualquer abordagem que use operações bit a bit restringe o intervalo de saída a -2147483648 10 (-2 31 ) - 2147483647 10 (2 31 -1).
No entanto, se as operações bit a bit forem evitadas e a representação de ponto flutuante de 64 bits for preservada usando apenas operações matemáticas, podemos converter com segurança qualquer número inteiro seguro na notação binária complementar de dois bits de 64 bits, estendendo o sinal de 53 bits
twosComplement
:Para navegadores mais antigos, existem polyfills para as seguintes funções e valores:
Number.isSafeInteger()
Number.isInteger()
Number.MAX_SAFE_INTEGER
String.prototype.padStart()
Como um bônus adicional, você pode suportar qualquer raiz (2–36) se realizar a conversão do complemento de dois para números negativos em dígitos ⌈64 / log 2 (raiz) by usando
BigInt
:Se você estiver interessado na minha resposta antiga que usou a
ArrayBuffer
para criar uma união entre aFloat64Array
e aUint16Array
, consulte o histórico de revisões desta resposta .fonte
-(2**53)-1
a2**53-1
em vez de apenas-(2**31)
a2**31-1
como a resposta de Annan.Uma solução que eu consideraria adequada para 32 bits é o código no final desta resposta, que é de developer.mozilla.org (MDN), mas com algumas linhas adicionadas para A) formatação e B), verificando se o número está no intervalo.
Alguns sugeriram
x.toString(2)
que não funciona para negativos, apenas coloca um sinal de menos para eles, o que não é bom.Fernando mencionou uma solução simples,
(x>>>0).toString(2);
que é boa para negativos, mas tem um pequeno problema quando x é positivo. Ele tem a saída começando com 1, que para números positivos não é o complemento adequado de 2s.Qualquer pessoa que não entenda o fato de números positivos começando com 0 e números negativos com 1, em complemento 2s, pode verificar esse SO QnA em complemento 2s. O que é o "Complemento 2"?
Uma solução poderia envolver a adição de um 0 para números positivos, o que fiz em uma revisão anterior desta resposta. E pode-se aceitar algumas vezes ter um número de 33 bits, ou se pode garantir que o número a converter esteja dentro do intervalo - (2 ^ 31) <= x <2 ^ 31-1. Portanto, o número é sempre 32 bits. Mas, em vez de fazer isso, você pode usar esta solução no mozilla.org
A resposta e o código de Patrick são longos e aparentemente funcionam para 64 bits, mas tinham um bug que um comentarista encontrou e o comentarista corrigiu o bug de patrick, mas patrick possui um "número mágico" em seu código que ele não comentou e que possui. esquecido e patrick não entende mais completamente seu próprio código / por que ele funciona.
Annan tinha alguma terminologia incorreta e pouco clara, mas mencionou uma solução por developer.mozilla.org https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators Isso funciona para números de 32 bits.
O código é bastante compacto, uma função de três linhas.
Mas eu adicionei um regex para formatar a saída em grupos de 8 bits. Baseado em Como imprimir um número com vírgulas como separadores de milhares em JavaScript (eu apenas o alterei de agrupá-lo em 3s da direita para a esquerda e adicionar vírgulas , para agrupar em 8s da direita para a esquerda e adicionar espaços )
E, enquanto o mozilla fez um comentário sobre o tamanho do nMask (o número alimentado) .. que ele deve estar dentro do alcance, eles não testaram ou lançaram um erro quando o número está fora do alcance, então eu acrescentou isso.
Não sei por que eles nomearam o parâmetro 'nMask', mas deixarei como está.
Referência: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
fonte
Você pode escrever sua própria função que retorna uma matriz de bits. Exemplo de como converter número em bits
Divisor Dividendo bits / restante
2 9 1
2 4 | 0 0
2 2 0 0
~ 1 | ~
exemplo da linha acima: 2 * 4 = 8 e o restante é 1, então 9 = 1 0 0 1
Leia os restantes de baixo para cima. Dígito 1 no meio para cima.
fonte
Math.floor(number%2)
vez denumber = Math.floor(number/2)
?Eu usei uma abordagem diferente para criar algo que faça isso. Decidi não usar esse código no meu projeto, mas pensei em deixá-lo em algum lugar relevante, caso seja útil para alguém.
fonte
Mais uma alternativa
fonte
Este é o meu código:
fonte
Essa é a solução. É bem simples, de fato
fonte