Я хотел бы видеть целые числа, положительные или отрицательные, в двоичном виде.
Скорее как этот вопрос , но для JavaScript.
Я хотел бы видеть целые числа, положительные или отрицательные, в двоичном виде.
Скорее как этот вопрос , но для JavaScript.
Ответы:
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
источник здесь
ОБНОВИТЬ:
Это будет работать только для положительных чисел, 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 /programming/10936600/javascript-decimal-to-binary-64-bit
*/
return (~dec).toString(2);
}
}
Я получил некоторую помощь отсюда
-3
возврат 1
). Также я считаю, что dec > 0
должно быть dec >= 0
, которое должно по крайней мере исправить 0. Потому что dec2Bin(0)
возвращается 10
.
Двоичный файл в «преобразовать в двоичный» может относиться к трем основным вещам. Позиционная система счисления, двоичное представление в памяти или 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"
(42).toString(2)
42..toString(2)
1.
то же, что 1.0
или просто 1
(и аналогично вы можете опустить часть раньше и написать .5
вместо 0.5
). Таким образом, в примере первая точка - это десятичный разделитель, который является частью числа, а вторая точка - это оператор точки для вызова метода для этого числа. Вы должны использовать две точки (или заключить число в круглые скобки) и не можете просто написать, 42.toString(2)
потому что анализатор видит точку как десятичный разделитель и выдает ошибку из-за пропущенного оператора точки.
Этот ответ пытается адресовать входы с абсолютным значением в диапазоне 2147483648 10 (2 31 ) - 9007199254740991 10 (2 53 -1).
В JavaScript числа хранятся в 64-битном представлении с плавающей запятой , но побитовые операции приводят их к 32-битным целым числам в формате дополнения до двух , поэтому любой подход, использующий побитовые операции, ограничивает диапазон вывода до -2147483648 10 (-2 31 ) - 2147483647 10 (2 31 -1).
Однако, если побитовые операции исключаются и 64-битное представление с плавающей запятой сохраняется с использованием только математических операций, мы можем надежно преобразовать любое безопасное целое число в 64-битную двоичную запись дополнения до двух, расширяя знак 53-бит 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}
В старых браузерах существуют полифилы для следующих функций и значений:
В качестве дополнительного бонуса вы можете поддержать любое основание (2–36), если выполните преобразование дополнения до двух для отрицательных чисел в ⌈64 / log 2 (основание) ⌉, используя 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}
Если вас интересует мой старый ответ, в котором ArrayBuffer
для создания союза между a Float64Array
и a использовался знак « Uint16Array
пожалуйста», обратитесь к истории изменений этого ответа .
-(2**53)-1
чтобы 2**53-1
вместо того , чтобы просто , -(2**31)
чтобы 2**31-1
как ответ Аннана.
Решение, которое я выбрал бы для 32-битного кода, - это конец этого ответа, код от developer.mozilla.org (MDN), но с некоторыми добавленными строками для A) форматирования и B) проверки того, что номер находится в диапазоне.
Некоторые предположили, x.toString(2)
что это не работает для негативов, для них просто вставляется знак минус, что бесполезно.
Фернандо упомянул простое решение, (x>>>0).toString(2);
которое подходит для негативов, но имеет небольшую проблему, когда х положительно. Вывод начинается с 1, что для положительных чисел не является правильным дополнением 2s.
Любой, кто не понимает факт положительных чисел, начинающихся с 0 и отрицательных чисел с 1, в дополнении 2s, может проверить эту SO QnA на дополнении 2s. Что такое «дополнение 2»?
Решение может заключаться в добавлении 0 для положительных чисел, что я и сделал в более ранней редакции этого ответа. И иногда можно принять 33-битное число или убедиться, что конвертируемое число находится в пределах диапазона - (2 ^ 31) <= x <2 ^ 31-1. Таким образом, число всегда составляет 32 бита. Но вместо того, чтобы сделать это, вы можете пойти с этим решением на mozilla.org
Ответ и код Патрика длинный и, по-видимому, работает для 64-битной системы, но имел ошибку, которую нашел комментатор, и комментатор исправил ошибку Патрика, но у Патрика в коде есть какое-то «магическое число», о котором он не комментировал и имеет о котором забыли, и Патрик больше не полностью понимает свой собственный код / почему он работает.
У Аннана была неправильная и неясная терминология, но он упомянул решение от developer.mozilla.org https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators. Это работает для 32-разрядных чисел.
Код довольно компактный, функция из трех строк.
Но я добавил регулярное выражение для форматирования вывода в группы по 8 бит. Основано на том, как напечатать число с запятыми в качестве разделителей тысяч в JavaScript (я только что изменил его: сгруппировать его в 3 с справа налево и добавить запятые , сгруппировать в 8 с справа налево и добавить пробелы )
И хотя mozilla прокомментировала размер nMask (число вводимых) ... что он должен находиться в диапазоне, они не проверяли и не выдавали ошибку, когда число выходит за пределы диапазона, поэтому я добавил это.
Я не уверен, почему они назвали свой параметр 'nMask', но я оставлю это как есть.
Ссылка: 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"
Вы можете написать свою собственную функцию, которая возвращает массив битов. Пример как преобразовать число в биты
Пример вышеприведенной строки: 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 посередине вверх.
Math.floor(number%2)
вместо number = Math.floor(number/2)
?
Я использовал другой подход, чтобы придумать что-то, что делает это. Я решил не использовать этот код в своем проекте, но я решил оставить его где-нибудь актуальным на случай, если он кому-нибудь пригодится.
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("---");
Еще одна альтернатива
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));
Это мой код:
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, we’re passing in 2 to
get a string representation of the binary for the base 10 number 100,
i.e. 1100100.
*/