Я хотів би бачити цілі числа, додатні чи негативні, у двійкових.
Це швидше, як це питання , але для 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 (radix) ⌉, використовуючи 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 (я щойно доповнив його, згрупувавши його в 3s справа наліво та додавши коми , до групування в 8s справа наліво та додавання пробілів )
І, хоча 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.
*/