Me gustaría ver enteros, positivos o negativos, en binario.
Más bien como esta pregunta , pero para JavaScript.
Me gustaría ver enteros, positivos o negativos, en binario.
Más bien como esta pregunta , pero para JavaScript.
Respuestas:
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
dec2bin(1); // 1
dec2bin(-1); // 11111111111111111111111111111111
dec2bin(256); // 100000000
dec2bin(-256); // 11111111111111111111111100000000
Puede usar la Number.toString(2)
función, pero tiene algunos problemas al representar números negativos. Por ejemplo, la (-1).toString(2)
salida es "-1"
.
Para solucionar este problema, puede usar el operador bit a la derecha sin signo ( >>>
) para forzar su número a un entero sin signo.
Si ejecuta (-1 >>> 0).toString(2)
, desplazará su número 0 bits hacia la derecha, lo que no cambia el número en sí, pero se representará como un entero sin signo. El código anterior saldrá "11111111111111111111111111111111"
correctamente.
Esta pregunta tiene más explicaciones.
-3 >>> 0
(desplazamiento lógico a la derecha) coacciona sus argumentos a enteros sin signo, razón por la cual obtiene la representación de complemento de dos de 32 bits de -3.
Tratar
num.toString(2);
El 2 es la raíz y puede ser cualquier base entre 2 y 36
fuente aquí
ACTUALIZAR:
Esto solo funcionará para números positivos, Javascript representa enteros binarios negativos en notación de complemento a dos. Hice esta pequeña función que debería funcionar, no la he probado correctamente:
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);
}
}
Tuve algo de ayuda de aquí
-3
devoluciones 1
). También creo que dec > 0
debería ser dec >= 0
, que al menos debería arreglar 0. Porque dec2Bin(0)
devuelve 10
.
El binario en 'convertir a binario' puede referirse a tres cosas principales. El sistema de números posicionales, la representación binaria en memoria o cadenas de bits de 32 bits. (para cadenas de bits de 64 bits, ver la respuesta de Patrick Roberts )
1. Sistema de numeración
(123456).toString(2)
convertirá números al sistema de numeración posicional de base 2 . En este sistema, los números negativos se escriben con signos menos al igual que en decimal.
2. Representación interna
La representación interna de los números es de coma flotante de 64 bits y en esta respuesta se analizan algunas limitaciones . No hay una manera fácil de crear una representación de cadena de bits de esto en JavaScript ni acceder a bits específicos.
3. Máscaras y operadores bit a bit
MDN tiene una buena visión general de cómo funcionan los operadores bit a bit. En tono rimbombante:
Los operadores bit a bit tratan sus operandos como una secuencia de 32 bits (ceros y unos)
Antes de aplicar las operaciones, los números de coma flotante de 64 bits se convierten en enteros con signo de 32 bits. Después de que se convierten de nuevo.
Aquí está el código de ejemplo MDN para convertir números en cadenas de 32 bits.
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"
Una forma simple es solo ...
Number(42).toString(2);
// "101010"
(42).toString(2)
42..toString(2)
1.
cuál es igual 1.0
o solo 1
(y de manera similar también puede omitir la parte anterior y escribir en .5
lugar de 0.5
). Entonces, en el ejemplo, el primer punto es el separador decimal que es parte del número y el segundo punto es el operador de punto para llamar al método en ese número. Debe usar dos puntos (o ajustar el número entre paréntesis) y no puede simplemente escribir 42.toString(2)
porque el analizador ve el punto como separador decimal y arroja un error debido a que falta un operador de punto.
Esta respuesta intenta direccionar entradas con un valor absoluto en el rango de 2147483648 10 (2 31 ) - 9007199254740991 10 (2 53 -1).
En JavaScript, los números se almacenan en representación de coma flotante de 64 bits , pero las operaciones bit a bit los obligan a números enteros de 32 bits en formato de complemento a dos , por lo que cualquier enfoque que utilice operaciones bit a bit restringe el rango de salida a -2147483648 10 (-2 31 ) - 2147483647 10 (2 31 -1).
Sin embargo, si se evitan las operaciones bit a bit y la representación de coma flotante de 64 bits se conserva utilizando solo operaciones matemáticas, podemos convertir de manera confiable cualquier entero seguro a la notación binaria del complemento a dos de 64 bits al extender el signo de 53 bits 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}
Para navegadores antiguos, existen polyfills para las siguientes funciones y valores:
Como una ventaja adicional, puede admitir cualquier raíz (2–36) si realiza la conversión del complemento de dos para números negativos en ⌈64 / log 2 (raíz) ⌉ dígitos 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}
Si está interesado en mi respuesta anterior que usaba un ArrayBuffer
para crear una unión entre ay Float64Array
a Uint16Array
, consulte el historial de revisión de esta respuesta .
-(2**53)-1
que 2**53-1
en lugar de limitarse -(2**31)
a 2**31-1
como respuesta de Annan.
Una solución con la que estaría bien para 32 bits es el código al final de esta respuesta, que es de developer.mozilla.org (MDN), pero con algunas líneas agregadas para el formato A) y B) verificar que el El número está en el rango.
Algunos sugirieron x.toString(2)
que no funciona para los negativos, simplemente coloca un signo menos allí para ellos, lo que no es bueno.
Fernando mencionó una solución simple (x>>>0).toString(2);
que está bien para los negativos, pero tiene un pequeño problema cuando x es positivo. Tiene la salida que comienza con 1, que para números positivos no es el complemento de 2s adecuado.
Cualquiera que no entienda el hecho de que los números positivos comienzan con 0 y los números negativos con 1, en el complemento de 2s, puede verificar este SO QnA en el complemento de 2s. ¿Qué es el "Complemento de 2"?
Una solución podría implicar anteponer un 0 para números positivos, lo que hice en una revisión anterior de esta respuesta. Y uno podría aceptar a veces tener un número de 33 bits, o uno podría asegurarse de que el número a convertir esté dentro del rango - (2 ^ 31) <= x <2 ^ 31-1. Entonces el número siempre es de 32 bits. Pero en lugar de hacer eso, puedes usar esta solución en mozilla.org
La respuesta y el código de Patrick son largos y aparentemente funcionan para 64 bits, pero tenía un error que encontró un comentarista, y el comentarista corrigió el error de Patrick, pero Patrick tiene algún "número mágico" en su código sobre el que no comentó y olvidado y patrick ya no entiende completamente su propio código / por qué funciona.
Annan tenía una terminología incorrecta y poco clara, pero mencionó una solución de developer.mozilla.org https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators Esto funciona para números de 32 bits.
El código es bastante compacto, una función de tres líneas.
Pero he agregado una expresión regular para formatear la salida en grupos de 8 bits. Basado en Cómo imprimir un número con comas como separadores de miles en JavaScript (solo lo modifiqué desde agruparlo en 3s de derecha a izquierda y agregar comas , hasta agruparlo en 8s de derecha a izquierda y agregar espacios )
Y, aunque Mozilla hizo un comentario sobre el tamaño de nMask (el número introducido) ... que tiene que estar dentro del rango, no probaron ni arrojaron un error cuando el número está fuera del rango, así que he agregó eso.
No estoy seguro de por qué nombraron su parámetro 'nMask', pero lo dejaré como está.
Referencia: 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"
Puede escribir su propia función que devuelve una matriz de bits. Ejemplo de cómo convertir números a bits
ejemplo de la línea anterior: 2 * 4 = 8 y el resto es 1, entonces 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
}
Lea los restos de abajo hacia arriba. Dígito 1 en el medio hacia arriba.
Math.floor(number%2)
lugar de number = Math.floor(number/2)
?
Utilicé un enfoque diferente para llegar a algo que haga esto. Decidí no usar este código en mi proyecto, pero pensé que lo dejaría en algún lugar relevante en caso de que sea útil para alguien.
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("---");
Una alternativa mas
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));
Este es mi código:
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();
Esta es la solución Es bastante simple de hecho
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.
*/