Id нравится видеть целые числа, положительные или отрицательные, в двоичном формате.
Скорее как этот вопрос, но для JavaScript.
Id нравится видеть целые числа, положительные или отрицательные, в двоичном формате.
Скорее как этот вопрос, но для JavaScript.
Этот ответ пытается адресовать целые числа с абсолютными значениями между 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;
}
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.
Попробуйте
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);
}
}
Мне помогли здесь
Двоичный файл в "преобразовать в двоичный" может относиться к трем основным вещам. Позиционная система счисления, двоичное представление в памяти или 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"
Простой способ - это просто...
Number(42).toString(2);
// "101010"
Примечание. Базовый (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" ?
Вы можете написать свою собственную функцию, которая возвращает массив бит. Пример преобразования числа в биты
пример выше строки: 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 в середине и сверху.
Я использовал другой подход, чтобы придумать что-то, что делает это. Я решил не использовать этот код в своем проекте, но решил оставить его где-нибудь актуальным, если он кому-нибудь пригодится.
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("---");
Это мой код:
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();
Это решение. Это довольно просто на самом деле
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.
*/