¿Cómo convertir un entero a binario en JavaScript?


Me gustaría ver enteros, positivos o negativos, en binario.

Más bien como esta pregunta, pero para JavaScript.

Author: Xufox, 2012-03-30

9 answers

Esta respuesta intenta abordar enteros con valores absolutos entre Number.MAX_SAFE_INTEGER (o 2**53-1) y 2**31. Las soluciones actuales solo abordan enteros con signo dentro de 32 bits, pero esta solución generará una forma de complemento de dos de 64 bits usando float64ToInt64Binary():

// IIFE to scope internal variables
var float64ToInt64Binary = (function () {
  // create union
  var flt64 = new Float64Array(1)
  var uint16 = new Uint16Array(flt64.buffer)
  // 2**53-1
  var MAX_SAFE = 9007199254740991
  // 2**31
  var MAX_INT32 = 2147483648

  function uint16ToBinary() {
    var bin64 = ''

    // generate padded binary string a word at a time
    for (var word = 0; word < 4; word++) {
      bin64 = uint16[word].toString(2).padStart(16, 0) + bin64
    }

    return bin64
  }

  return function float64ToInt64Binary(number) {
    // NaN would pass through Math.abs(number) > MAX_SAFE
    if (!(Math.abs(number) <= MAX_SAFE)) {
      throw new RangeError('Absolute value must be less than 2**53')
    }

    var sign = number < 0 ? 1 : 0

    // shortcut using other answer for sufficiently small range
    if (Math.abs(number) <= MAX_INT32) {
      return (number >>> 0).toString(2).padStart(64, sign)
    }

    // little endian byte ordering
    flt64[0] = number

    // subtract bias from exponent bits
    var exponent = ((uint16[3] & 0x7FF0) >> 4) - 1023

    // encode implicit leading bit of mantissa
    uint16[3] |= 0x10
    // clear exponent and sign bit
    uint16[3] &= 0x1F

    // check sign bit
    if (sign === 1) {
      // apply two's complement
      uint16[0] ^= 0xFFFF
      uint16[1] ^= 0xFFFF
      uint16[2] ^= 0xFFFF
      uint16[3] ^= 0xFFFF
      // propagate carry bit
      for (var word = 0; word < 3 && uint16[word] === 0xFFFF; word++) {
        // apply integer overflow
        uint16[word] = 0
      }

      // complete increment
      uint16[word]++
    }

    // only keep integer part of mantissa
    var bin64 = uint16ToBinary().substr(11, Math.max(exponent, 0))
    // sign-extend binary string
    return bin64.padStart(64, sign)
  }
})()

console.log('8')
console.log(float64ToInt64Binary(8))
console.log('-8')
console.log(float64ToInt64Binary(-8))
console.log('2**33-1')
console.log(float64ToInt64Binary(2**33-1))
console.log('-(2**33-1)')
console.log(float64ToInt64Binary(-(2**33-1)))
console.log('2**53-1')
console.log(float64ToInt64Binary(2**53-1))
console.log('-(2**53-1)')
console.log(float64ToInt64Binary(-(2**53-1)))
console.log('2**52')
console.log(float64ToInt64Binary(2**52))
console.log('-(2**52)')
console.log(float64ToInt64Binary(-(2**52)))
.as-console-wrapper {
  max-height: 100% !important;
}

Esta respuesta trata en gran medida con el formato de coma flotante de doble precisión IEEE-754 , ilustrado aquí:

IEEE - 754 Formato de coma flotante de doble precisión

   seee eeee eeee ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   [    uint16[3]    ] [    uint16[2]    ] [    uint16[1]    ] [    uint16[0]    ]
   [                                   flt64[0]                                  ]

   little endian byte ordering

   s = sign = uint16[3] >> 15
   e = exponent = (uint16[3] & 0x7FF) >> 4
   f = fraction

La forma en que funciona la solución es que crea una unión entre un número de coma flotante de 64 bits y una matriz de enteros de 16 bits sin signo en el orden de bytes little endian. Después de validar el rango de entrada de enteros, arroja la entrada a un número de punto flotante de doble precisión en el búfer, y luego usa la unión para obtener acceso de bits al valor y calcular la cadena binaria basada en el exponente binario imparcial y los bits de fracción.

La solución está implementada en ECMAScript 5 puro excepto por el uso de String#padStart(), que tiene un polyfill disponible aquí .

 9
Author: Patrick Roberts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-18 18:05:31

Respuesta:

function dec2bin(dec){
    return (dec >>> 0).toString(2);
}

dec2bin(1);    // 1
dec2bin(-1);   // 11111111111111111111111111111111
dec2bin(256);  // 100000000
dec2bin(-256); // 11111111111111111111111100000000

Puede utilizar Number.toString(2) función, pero tiene algunos problemas al representar números negativos. Por ejemplo, (-1).toString(2) la salida es "-1".

Para solucionar este problema, puede usar el operador de desplazamiento a la derecha sin signo(>>>) para coaccionar 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 sin signo entero. El código anterior mostrará "11111111111111111111111111111111" correctamente.

Esta pregunta tiene más explicación.

-3 >>> 0 (desplazamiento lógico correcto) coacciona sus argumentos a enteros sin signo, por lo que se obtiene la representación del complemento de los dos de 32 bits de -3.


Nota 1: esta respuesta espera un Número como argumento, así que conviértalo en consecuencia.

Nota 2: el resultado es la cadena a sin ceros a la izquierda, así que aplica relleno como usted necesita.

 339
Author: fernandosavio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-19 21:22:59

Intenta

num.toString(2);

El 2 es la raíz y puede ser cualquier base entre 2 y 36

Fuente aquí

ACTUALIZACIÓN:

Esto solo funcionará para números positivos, Javascript representa enteros binarios negativos en notación de complemento de dos. Hice esta pequeña función que debería hacer el truco, 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 https://stackoverflow.com/questions/10936600/javascript-decimal-to-binary-64-bit 
        */
        return (~dec).toString(2);
    }
}

Tuve algo de ayuda de aquí

 162
Author: Manatok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:32

El binario en "convertir a binario' puede referirse a tres cosas principales. El sistema numérico posicional, 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 numérico

(123456).toString(2) convertirá números al sistema de numeración posicional base 2 . En este sistema los números negativos se escriben con signos menos al igual que en decimal.

2. Representación Interna

El la representación interna de números es punto flotante de 64 bits y algunas limitaciones se discuten en esta respuesta. No hay una forma 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 Bitwise

MDN tiene una buena visión general de cómo funcionan los operadores bitwise. Importante:

Los operadores Bitwise tratan sus operandos como una secuencia de 32 bits (ceros y ones)

Antes de aplicar las operaciones, los números de puntos flotantes de 64 bits se convierten en enteros con signo de 32 bits. Después de que sean convertidos 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"
 41
Author: Annan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-25 02:58:38

Una manera simple es justa...

Number(42).toString(2);

// "101010"
 36
Author: ad rees,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-24 21:38:39

Nota - el (x>>>0).toString(2); básico tiene un pequeño problema cuando x es positivo. Tengo un código de ejemplo al final de mi respuesta que corrige ese problema con el método >>> mientras todavía usa >>>.

(-3>>>0).toString(2);

prints -3 in 2s complement.

1111111111101

Un ejemplo de trabajo

C:\>type n1.js
console.log(   (-3 >>> 0).toString(2)    );
C:\>
C:\>node n1.js
11111111111111111111111111111101

C:\>

Esto en la barra de URL es otra prueba rápida

javascript:alert((-3>>>0).toString(2))

Nota - El resultado es muy ligeramente defectuoso, ya que siempre comienza con un 1, que para números negativos está bien. Para números positivos debe anteponer un 0 al principio para que el resultado es realmente 2s complemento. Así que (8>>>0).toString(2) produce 1000 que no es realmente 8 en 2s complemento, pero anteponiendo que 0, por lo que es 01000, es correcto 8 en 2s complemento. En el complemento 2s apropiado, cualquier cadena de bits que comience con 0 es >=0, y cualquier cadena de bits que comience con 1, es negativa.

Por ejemplo, esto evita ese problema

// or x=-5  whatever number you want to view in binary  
x=5;   
if(x>0) prepend="0"; else prepend=""; 
alert(prepend+((x>>>0)).toString(2));

Las otras soluciones son la de Annan (aunque las explicaciones y definiciones de Annan están llenas de errores, tiene un código que produce el resultado correcto), y solución de Patrick.

Cualquiera que no entienda el hecho de los números positivos que comienzan con 0 y los números negativos con 1, en el complemento 2s, podría comprobar esto para QnA en el complemento 2s. ¿Qué es el Complemento de 2?

 8
Author: barlop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-26 12:35:50

Puede escribir su propia función que devuelve una matriz de bits. Ejemplo cómo convertir número a bits

Divisor / Dividendo/bits / resto

2 | 9 | 1

2 | 4 | 0

2 | 2 | 0

~ | 1 |~

Ejemplo de la línea anterior: 2 * 4 = 8 y el resto es 1 so 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
}

Lee los restos de abajo hacia arriba. Dígito 1 en el medio a la parte superior.

 6
Author: supritshah1289,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-02 22:36:13

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();
 -2
Author: Vincent William Rodriguez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-07 12:28:26

Esta es la solución . Es bastante simple como una cuestión 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.
        */
 -3
Author: Brian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-12 07:59:07