Как преобразовать целое число в двоичный код в JavaScript?

Id нравится видеть целые числа, положительные или отрицательные, в двоичном формате.

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

Ответ 1

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

Ответ 2

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.

Ответ 3

Попробуйте

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

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

Ответ 4

Двоичный файл в "преобразовать в двоичный" может относиться к трем основным вещам. Позиционная система счисления, двоичное представление в памяти или 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"

Ответ 5

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

Number(42).toString(2);

// "101010"

Ответ 6

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

(-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:\>

Это в строке URL является еще одним быстрым доказательством

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

Примечание. Результат очень немного ошибочен, поскольку он всегда начинается с 1, что для отрицательных чисел отлично. Для положительных чисел вы должны добавить 0 к началу так, чтобы результат был действительно дополнен двумя. Таким образом, (8>>>0).toString(2) производит 1000, что на самом деле не является 8 в дополнении 2s, но, полагая, что 0, делая его 01000, является правильным 8 в 2s дополнении. В правильном дополнении 2s любая битовая строка, начинающаяся с 0, равнa >= 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));

Другие решения являются одними из Annan (хотя объяснения и определения Annan полны ошибок, у него есть код, который дает правильный результат), и решение от Patrick.

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

Ответ 7

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

Делитель | Дивидендная | бит/остаточный

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 в середине и сверху.

Ответ 8

Я использовал другой подход, чтобы придумать что-то, что делает это. Я решил не использовать этот код в своем проекте, но решил оставить его где-нибудь актуальным, если он кому-нибудь пригодится.

  • Не использует сдвиг битов или приведение к двум дополнениям.
  • Вы выбираете количество получаемых битов (оно проверяет допустимые значения '8', '16', '32', но я полагаю, вы можете это изменить)
  • Вы выбираете, следует ли рассматривать его как целое число со знаком или без знака.
  • Он проверит наличие проблем с диапазоном, учитывая комбинацию со знаком/без знака и количеством битов, хотя вы захотите улучшить обработку ошибок.
  • Он также имеет "обратную" версию функции, которая преобразует биты обратно в int. Вам это понадобится, так как, вероятно, больше ничего не будет интерпретировать этот вывод: D

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

Ответ 9

Это мой код:

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

Ответ 10

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

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, were passing in 2 to 
         get a string representation of the binary for the base 10 number 100, 
         i.e. 1100100.
        */