Mi piacerebbe vedere numeri interi, positivi o negativi, in binario.
Un po 'come questa domanda , ma per JavaScript.
Mi piacerebbe vedere numeri interi, positivi o negativi, in binario.
Un po 'come questa domanda , ma per JavaScript.
Risposte:
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
dec2bin(1); // 1
dec2bin(-1); // 11111111111111111111111111111111
dec2bin(256); // 100000000
dec2bin(-256); // 11111111111111111111111100000000
È possibile utilizzare la Number.toString(2)
funzione, ma presenta alcuni problemi nella rappresentazione di numeri negativi. Ad esempio, l' (-1).toString(2)
output è "-1"
.
Per risolvere questo problema, è possibile utilizzare l'operatore bit a bit di spostamento a destra senza segno ( >>>
) per forzare il numero su un numero intero senza segno.
Se corri (-1 >>> 0).toString(2)
, sposterai il tuo numero 0 bit a destra, il che non cambia il numero stesso ma verrà rappresentato come un numero intero senza segno. Il codice sopra verrà emesso "11111111111111111111111111111111"
correttamente.
Questa domanda ha ulteriori spiegazioni.
-3 >>> 0
(shift logico destro) costringe i suoi argomenti a numeri interi senza segno, motivo per cui si ottiene la rappresentazione del complemento a due bit a 32 bit di -3.
Provare
num.toString(2);
Il 2 è la radice e può essere qualsiasi base tra 2 e 36
fonte qui
AGGIORNARE:
Funzionerà solo con numeri positivi, Javascript rappresenta numeri interi binari negativi nella notazione a due complementi. Ho fatto questa piccola funzione che dovrebbe fare il trucco, non l'ho testato correttamente:
function dec2Bin(dec)
{
if(dec >= 0) {
return dec.toString(2);
}
else {
/* Here you could represent the number in 2s compliment but this is not what
JS uses as its not sure how many bits are in your number range. There are
some suggestions /programming/10936600/javascript-decimal-to-binary-64-bit
*/
return (~dec).toString(2);
}
}
Ho avuto qualche aiuto da qui
-3
ritorni 1
). Inoltre credo che dec > 0
dovrebbe essere dec >= 0
, che dovrebbe almeno risolvere 0. Perché dec2Bin(0)
restituisce 10
.
Il binario in "converti in binario" può riferirsi a tre cose principali. Il sistema numerico posizionale, la rappresentazione binaria in memoria o bittrings a 32 bit. (per bittring a 64 bit, vedere la risposta di Patrick Roberts )
1. Sistema numerico
(123456).toString(2)
convertirà i numeri nel sistema numerico posizionale di base 2 . In questo sistema i numeri negativi sono scritti con segni meno proprio come in decimale.
2. Rappresentanza interna
La rappresentazione interna dei numeri è a virgola mobile a 64 bit e alcune limitazioni sono discusse in questa risposta . Non esiste un modo semplice per creare una rappresentazione di stringhe di bit in javascript né accedere a bit specifici.
3. Maschere e operatori bit a bit
MDN ha una buona panoramica di come funzionano gli operatori bit a bit. È importante sottolineare che:
Gli operatori bit a bit considerano i loro operandi come una sequenza di 32 bit (zero e uno)
Prima di applicare le operazioni, i numeri in virgola mobile a 64 bit vengono espressi in numeri interi con segno a 32 bit. Dopo che sono stati riconvertiti.
Ecco il codice di esempio MDN per convertire i numeri in stringhe a 32 bit.
function createBinaryString (nMask) {
// nMask must be between -2147483648 and 2147483647
for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32;
nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
return sMask;
}
createBinaryString(0) //-> "00000000000000000000000000000000"
createBinaryString(123) //-> "00000000000000000000000001111011"
createBinaryString(-1) //-> "11111111111111111111111111111111"
createBinaryString(-1123456) //-> "11111111111011101101101110000000"
createBinaryString(0x7fffffff) //-> "01111111111111111111111111111111"
Un modo semplice è solo ...
Number(42).toString(2);
// "101010"
(42).toString(2)
42..toString(2)
1.
che è uguale 1.0
o solo 1
(e allo stesso modo puoi anche omettere la parte prima e scrivere .5
invece di 0.5
). Quindi nell'esempio il primo punto è il separatore decimale che fa parte del numero e il secondo punto è l'operatore punto per chiamare il metodo su quel numero. Devi usare due punti (o racchiudere il numero tra parentesi) e non puoi semplicemente scrivere 42.toString(2)
perché il parser vede il punto come separatore decimale e genera un errore a causa di un operatore punto mancante.
Questa risposta tenta di indirizzare gli input con un valore assoluto nell'intervallo 2147483648 10 (2 31 ) - 9007199254740991 10 (2 53 -1).
In JavaScript, i numeri sono memorizzati nella rappresentazione in virgola mobile a 64 bit , ma le operazioni bit a bit li costringono a numeri interi a 32 bit in formato complemento a due , quindi qualsiasi approccio che utilizza operazioni a bit limita l'intervallo di output a -2147483648 10 (-2 31 ) - 2147483647 10 (2 31 -1).
Tuttavia, se si evitano operazioni bit a bit e la rappresentazione in virgola mobile a 64 bit viene preservata utilizzando solo operazioni matematiche, è possibile convertire in modo affidabile qualsiasi numero intero sicuro in notazione binaria del complemento a due bit a 64 bit estendendo il segno a 53 bit twosComplement
:
function toBinary (value) {
if (!Number.isSafeInteger(value)) {
throw new TypeError('value must be a safe integer');
}
const negative = value < 0;
const twosComplement = negative ? Number.MAX_SAFE_INTEGER + value + 1 : value;
const signExtend = negative ? '1' : '0';
return twosComplement.toString(2).padStart(53, '0').padStart(64, signExtend);
}
function format (value) {
console.log(value.toString().padStart(64));
console.log(value.toString(2).padStart(64));
console.log(toBinary(value));
}
format(8);
format(-8);
format(2**33-1);
format(-(2**33-1));
format(2**53-1);
format(-(2**53-1));
format(2**52);
format(-(2**52));
format(2**52+1);
format(-(2**52+1));
.as-console-wrapper{max-height:100%!important}
Per i browser più vecchi, esistono polyfill per le seguenti funzioni e valori:
Come bonus aggiuntivo, puoi supportare qualsiasi radix (2–36) se esegui la conversione del complemento a due per numeri negativi in ⌈64 / log 2 (radix) ⌉ cifre usando BigInt
:
function toRadix (value, radix) {
if (!Number.isSafeInteger(value)) {
throw new TypeError('value must be a safe integer');
}
const digits = Math.ceil(64 / Math.log2(radix));
const twosComplement = value < 0
? BigInt(radix) ** BigInt(digits) + BigInt(value)
: value;
return twosComplement.toString(radix).padStart(digits, '0');
}
console.log(toRadix(0xcba9876543210, 2));
console.log(toRadix(-0xcba9876543210, 2));
console.log(toRadix(0xcba9876543210, 16));
console.log(toRadix(-0xcba9876543210, 16));
console.log(toRadix(0x1032547698bac, 2));
console.log(toRadix(-0x1032547698bac, 2));
console.log(toRadix(0x1032547698bac, 16));
console.log(toRadix(-0x1032547698bac, 16));
.as-console-wrapper{max-height:100%!important}
Se sei interessato alla mia vecchia risposta che ha usato un ArrayBuffer
per creare un'unione tra una Float64Array
e una Uint16Array
, fai riferimento alla cronologia delle revisioni di questa risposta .
-(2**53)-1
a 2**53-1
invece di -(2**31)
a 2**31-1
come la risposta di Annan.
Una soluzione con cui andrei bene per 32 bit, è il codice alla fine di questa risposta, che proviene da developer.mozilla.org (MDN), ma con alcune righe aggiunte per la formattazione A) e B) verificando che il il numero è nell'intervallo.
Alcuni hanno suggerito x.toString(2)
che non funziona per i negativi, attacca solo un segno meno lì per loro, il che non va bene.
Fernando ha menzionato una soluzione semplice (x>>>0).toString(2);
che va bene per i negativi, ma ha un leggero problema quando x è positivo. Ha l'output che inizia con 1, che per i numeri positivi non è un complemento corretto per 2 secondi.
Chiunque non capisca il fatto di numeri positivi che iniziano con 0 e numeri negativi con 1, nel complemento 2s, potrebbe controllare questo QnA SO sul complemento 2s. Che cos'è il "complemento di 2"?
Una soluzione potrebbe comportare anteporre uno 0 per i numeri positivi, cosa che ho fatto in una precedente revisione di questa risposta. E a volte si potrebbe accettare di avere un numero di 33 bit, oppure si potrebbe assicurarsi che il numero da convertire sia compreso nell'intervallo - (2 ^ 31) <= x <2 ^ 31-1. Quindi il numero è sempre a 32 bit. Ma invece di farlo, puoi scegliere questa soluzione su mozilla.org
La risposta e il codice di Patrick sono lunghi e apparentemente funzionano a 64 bit, ma avevano un bug che un commentatore ha trovato e il commentatore ha corretto il bug di patrick, ma patrick ha un "numero magico" nel suo codice di cui non ha commentato e ha dimenticato e patrick non capisce più completamente il proprio codice / perché funziona.
Annan aveva una terminologia errata e poco chiara ma menzionava una soluzione di developer.mozilla.org https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators Funziona con numeri a 32 bit.
Il codice è piuttosto compatto, una funzione di tre righe.
Ma ho aggiunto una regex per formattare l'output in gruppi di 8 bit. Basato su Come stampare un numero con virgole come migliaia di separatori in JavaScript (l'ho appena modificato dal raggruppamento in 3 secondi da destra a sinistra e l'aggiunta di virgole , al raggruppamento in 8 secondi da destra a sinistra e l'aggiunta di spazi )
E, mentre mozilla ha fatto un commento sulla dimensione di nMask (il numero inserito) .. che deve essere compreso nell'intervallo, non hanno testato o generato un errore quando il numero è fuori intervallo, quindi ho aggiunto quello.
Non sono sicuro del motivo per cui hanno chiamato il loro parametro 'nMask' ma lo lascerò così com'è.
Riferimento: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
function createBinaryString(nMask) {
// nMask must be between -2147483648 and 2147483647
if (nMask > 2**31-1)
throw "number too large. number shouldn't be > 2**31-1"; //added
if (nMask < -1*(2**31))
throw "number too far negative, number shouldn't be < 2**31" //added
for (var nFlag = 0, nShifted = nMask, sMask = ''; nFlag < 32;
nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
sMask=sMask.replace(/\B(?=(.{8})+(?!.))/g, " ") // added
return sMask;
}
console.log(createBinaryString(-1)) // "11111111 11111111 11111111 11111111"
console.log(createBinaryString(1024)) // "00000000 00000000 00000100 00000000"
console.log(createBinaryString(-2)) // "11111111 11111111 11111111 11111110"
console.log(createBinaryString(-1024)) // "11111111 11111111 11111100 00000000"
È possibile scrivere la propria funzione che restituisce una matrice di bit. Esempio come convertire il numero in bit
esempio della riga sopra: 2 * 4 = 8 e il resto è 1, quindi 9 = 1 0 0 1
function numToBit(num){
var number = num
var result = []
while(number >= 1 ){
result.unshift(Math.floor(number%2))
number = number/2
}
return result
}
Leggi i resti dal basso verso l'alto. Cifra 1 al centro verso l'alto.
Math.floor(number%2)
invece di number = Math.floor(number/2)
?
Ho usato un approccio diverso per trovare qualcosa che lo facesse. Ho deciso di non utilizzare questo codice nel mio progetto, ma ho pensato di lasciarlo in un posto rilevante nel caso fosse utile per qualcuno.
function intToBitString(input, size, unsigned) {
if ([8, 16, 32].indexOf(size) == -1) {
throw "invalid params";
}
var min = unsigned ? 0 : - (2 ** size / 2);
var limit = unsigned ? 2 ** size : 2 ** size / 2;
if (!Number.isInteger(input) || input < min || input >= limit) {
throw "out of range or not an int";
}
if (!unsigned) {
input += limit;
}
var binary = input.toString(2).replace(/^-/, '');
return binary.padStart(size, '0');
}
function bitStringToInt(input, size, unsigned) {
if ([8, 16, 32].indexOf(size) == -1) {
throw "invalid params";
}
input = parseInt(input, 2);
if (!unsigned) {
input -= 2 ** size / 2;
}
return input;
}
// EXAMPLES
var res;
console.log("(uint8)10");
res = intToBitString(10, 8, true);
console.log("intToBitString(res, 8, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 8, true));
console.log("---");
console.log("(uint8)127");
res = intToBitString(127, 8, true);
console.log("intToBitString(res, 8, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 8, true));
console.log("---");
console.log("(int8)127");
res = intToBitString(127, 8, false);
console.log("intToBitString(res, 8, false)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 8, false));
console.log("---");
console.log("(int8)-128");
res = intToBitString(-128, 8, false);
console.log("intToBitString(res, 8, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 8, true));
console.log("---");
console.log("(uint16)5000");
res = intToBitString(5000, 16, true);
console.log("intToBitString(res, 16, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 16, true));
console.log("---");
console.log("(uint32)5000");
res = intToBitString(5000, 32, true);
console.log("intToBitString(res, 32, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 32, true));
console.log("---");
Un'altra alternativa
const decToBin = dec => {
let bin = '';
let f = false;
while (!f) {
bin = bin + (dec % 2);
dec = Math.trunc(dec / 2);
if (dec === 0 ) f = true;
}
return bin.split("").reverse().join("");
}
console.log(decToBin(0));
console.log(decToBin(1));
console.log(decToBin(2));
console.log(decToBin(3));
console.log(decToBin(4));
console.log(decToBin(5));
console.log(decToBin(6));
Questo è il mio codice:
var x = prompt("enter number", "7");
var i = 0;
var binaryvar = " ";
function add(n) {
if (n == 0) {
binaryvar = "0" + binaryvar;
}
else {
binaryvar = "1" + binaryvar;
}
}
function binary() {
while (i < 1) {
if (x == 1) {
add(1);
document.write(binaryvar);
break;
}
else {
if (x % 2 == 0) {
x = x / 2;
add(0);
}
else {
x = (x - 1) / 2;
add(1);
}
}
}
}
binary();
Questa è la soluzione È piuttosto semplice
function binaries(num1){
var str = num1.toString(2)
return(console.log('The binary form of ' + num1 + ' is: ' + str))
}
binaries(3
)
/*
According to MDN, Number.prototype.toString() overrides
Object.prototype.toString() with the useful distinction that you can
pass in a single integer argument. This argument is an optional radix,
numbers 2 to 36 allowed.So in the example above, we’re passing in 2 to
get a string representation of the binary for the base 10 number 100,
i.e. 1100100.
*/