Как мне преобразовать целое число в двоичное в JavaScript? - PullRequest
248 голосов
/ 30 марта 2012

Я хотел бы видеть целые числа, положительные или отрицательные, в двоичном виде.

Скорее, как этот вопрос , но для JavaScript.

Ответы [ 9 ]

418 голосов
/ 22 апреля 2013

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

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

Вы можете использовать функцию Number.toString(2), но у нее есть некоторые проблемы при представлении отрицательных чисел. Например, (-1).toString(2) вывод равен "-1".

Чтобы устранить эту проблему, вы можете использовать битовый оператор беззнакового сдвига вправо (>>>), чтобы привести ваше число к целому числу без знака.

Если вы запустите (-1 >>> 0).toString(2), вы сдвинете свои биты числа 0 вправо, что само по себе не изменит число, но будет представлено как целое число без знака. Приведенный выше код будет правильно выводить "11111111111111111111111111111111".

Этот вопрос имеет дальнейшее объяснение.

-3 >>> 0 (правый логический сдвиг) приводит свои аргументы к целым числам без знака, поэтому вы получаете 32-битное представление дополнения до двух -3.


Примечание 1 : этот ответ ожидает число в качестве аргумента, поэтому преобразуйте его соответствующим образом.

Примечание 2 : в результате получается строка без начальных нулей, поэтому применяйте заполнение по мере необходимости.

180 голосов
/ 30 марта 2012

Попробуйте

num.toString(2);

2 является основанием и может быть любым основанием от 2 до 36

источник здесь

UPDATE:

Это будет работать только для положительных чисел, Javascript представляет отрицательные двоичные целые числа в двоичной записи. Я сделал эту маленькую функцию, которая должна была сделать свое дело, я не проверил ее должным образом:

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);
    }
}

Мне помогла здесь

45 голосов
/ 11 июня 2014

Двоичный код в «преобразовать в двоичный» может относиться к трем основным вещам.Позиционная система счисления, двоичное представление в памяти или 32-битные цепочки битов.(для 64-битных цепочек см. ответ Патрика Робертса )

1.Система счисления

(123456).toString(2) преобразует числа в основную 2 позиционную систему счисления .В этой системе отрицательные числа пишутся со знаками минус, точно так же как в десятичной дроби.

2.Внутреннее представление

Внутреннее представление чисел - 64-битная с плавающей запятой , а некоторые ограничения обсуждаются в в этом ответе . не существует простого способа для создания представления битовой строки этого в javascript или доступа к определенным битам.

3.Маски и побитовые операторы

MDN имеет хороший обзор того, как работают побитовые операторы.Важно:

Битовые операторы обрабатывают свои операнды как последовательность 32 бит (нули и единицы)

Перед применением операций 64-битное плавающее значениечисла точек приводятся к 32-битным целым числам со знаком.После того, как они преобразованы обратно.

Вот пример кода MDN для преобразования чисел в 32-битные строки.

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"
39 голосов
/ 16 августа 2013

Простой способ это просто ...

Number(42).toString(2);

// "101010"
22 голосов
/ 24 июля 2017

Этот ответ пытается адресовать целые числа с абсолютными значениями от Number.MAX_SAFE_INTEGER (или 2**53-1) до 2**31. Текущие решения адресуют только целые числа со знаком в пределах 32 битов, но это решение будет выводить в 64-битной форме дополнения до двух, используя 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) - 1022

    // 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)))
console.log('2**52+1')
console.log(float64ToInt64Binary(2**52+1))
console.log('-(2**52+1)')
console.log(float64ToInt64Binary(-(2**52+1)))
.as-console-wrapper {
  max-height: 100% !important;
}

Этот ответ в значительной степени относится к IEEE-754 формату с плавающей запятой двойной точности , показанному здесь:

IEEE-754 Double-precision floating-point format

   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

Способ решения состоит в том, что он создает объединение между 64-разрядным числом с плавающей запятой и 16-разрядным целочисленным массивом без знака в порядке байтов с прямым порядком байтов. После проверки целочисленного входного диапазона он преобразует ввод в число с плавающей запятой двойной точности в буфере, а затем использует объединение, чтобы получить битовый доступ к значению и вычислить двоичную строку на основе несмещенного двоичного показателя и битов дроби. 1021 *

Решение реализовано в чистом ECMAScript 5, за исключением использования String#padStart(), который имеет доступный здесь полифилл .

9 голосов
/ 17 ноября 2015

Примечание - базовый (x>>>0).toString(2); имеет небольшую проблему, когда х положительный. У меня есть пример кода в конце моего ответа, который исправляет эту проблему с помощью метода >>>, все еще используя >>>.

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

prints -3 in 2s complement.

1111111111101

Рабочий пример

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

C:\>

Это в адресной строке еще одно быстрое доказательство

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

Примечание. Результат очень слабый, он всегда начинается с 1, что для отрицательных чисел вполне подойдет. Для положительных чисел вы должны добавить 0 к началу, чтобы результат был действительно дополнением 2s. Таким образом, (8>>>0).toString(2) производит 1000, которое на самом деле не является дополнением 8 в 2 с, но предваряя это 0, делая его 01000, является правильным дополнением 8 в 2 с. В правильном дополнении 2s любая битовая строка, начинающаяся с 0,>> 0, а любая битовая строка, начинающаяся с 1, является отрицательной.

например. это решает эту проблему

// 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));

Другие решения принадлежат Аннану (хотя объяснения и определения Аннана полны ошибок, у него есть код, который дает правильный вывод) и решение от Патрика.

Любой, кто не понимает факт положительных чисел, начинающихся с 0 и отрицательных чисел с 1, в дополнении 2s, может проверить эту SO QnA на дополнении 2s. Что такое «дополнение 2»?

6 голосов
/ 03 ноября 2016

Вы можете написать свою собственную функцию, которая возвращает массив битов.Пример преобразования числа в биты

Divisor |Дивидендная |биты / остаток

2 |9 |1

2 |4 |0

2 |2 |0

~ |1 | ~

пример вышеприведенной строки: 2 * 4 = 8, а остаток равен 1, поэтому 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
}

Считывание остатков снизу вверх.Цифра 1 посередине вверх.

0 голосов
/ 12 июня 2018

Это решение.Это довольно просто на самом деле

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.
        */
0 голосов
/ 07 ноября 2017

Это мой код:

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();
...