Tôi muốn thấy số nguyên, tích cực hoặc tiêu cực, trong nhị phân.
Thay vì câu hỏi này , nhưng đối với JavaScript.
Tôi muốn thấy số nguyên, tích cực hoặc tiêu cực, trong nhị phân.
Thay vì câu hỏi này , nhưng đối với JavaScript.
Câu trả lời:
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
dec2bin(1); // 1
dec2bin(-1); // 11111111111111111111111111111111
dec2bin(256); // 100000000
dec2bin(-256); // 11111111111111111111111100000000
Bạn có thể sử dụng Number.toString(2)
hàm, nhưng nó có một số vấn đề khi biểu diễn số âm. Ví dụ, (-1).toString(2)
đầu ra là "-1"
.
Để khắc phục sự cố này, bạn có thể sử dụng toán tử bit shift phải không dấu ( >>>
) để ép số của bạn thành một số nguyên không dấu.
Nếu bạn chạy, (-1 >>> 0).toString(2)
bạn sẽ dịch chuyển số bit 0 của mình sang phải, điều này không tự thay đổi số nhưng nó sẽ được biểu diễn dưới dạng một số nguyên không dấu. Đoạn mã trên sẽ xuất ra "11111111111111111111111111111111"
chính xác.
Câu hỏi này có giải thích thêm.
-3 >>> 0
(dịch chuyển logic phải) ép buộc các đối số của nó thành các số nguyên không dấu, đó là lý do tại sao bạn có biểu diễn bổ sung của 32-bit hai -3.
Thử
num.toString(2);
2 là cơ số và có thể là bất kỳ cơ sở nào giữa 2 và 36
nguồn ở đây
CẬP NHẬT:
Điều này sẽ chỉ hoạt động cho các số dương, Javascript đại diện cho số nguyên nhị phân âm trong ký hiệu bổ sung của hai. Tôi đã thực hiện chức năng nhỏ này để thực hiện thủ thuật, tôi đã không kiểm tra đúng cách:
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);
}
}
Tôi đã có một số trợ giúp từ đây
-3
trả về 1
). Ngoài ra tôi tin rằng dec > 0
nên dec >= 0
, ít nhất nên sửa 0. Vì dec2Bin(0)
trả về 10
.
Nhị phân trong 'chuyển đổi thành nhị phân' có thể đề cập đến ba điều chính. Hệ thống số vị trí, biểu diễn nhị phân trong bộ nhớ hoặc bitstr 32 bit. (đối với bitstr 64 bit, xem câu trả lời của Patrick Roberts )
1. Hệ thống số
(123456).toString(2)
sẽ chuyển đổi số sang hệ thống số vị trí cơ sở 2 . Trong hệ thống này, số âm được viết với dấu trừ giống như số thập phân.
2. Đại diện nội bộ
Biểu diễn bên trong của các số là dấu phẩy động 64 bit và một số hạn chế được thảo luận trong câu trả lời này . Không có cách nào dễ dàng để tạo một đại diện chuỗi bit của điều này trong javascript cũng như truy cập các bit cụ thể.
3. Mặt nạ & Toán tử bitwise
MDN có một tổng quan tốt về cách các toán tử bitwise hoạt động. Quan trọng:
Toán tử bitwise xử lý toán hạng của chúng như một chuỗi gồm 32 bit (số không và số)
Trước khi các hoạt động được áp dụng, các số dấu phẩy động 64 bit được chuyển thành các số nguyên có chữ ký 32 bit. Sau khi chúng được chuyển đổi trở lại.
Dưới đây là mã ví dụ MDN để chuyển đổi số thành chuỗi 32 bit.
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"
Một cách đơn giản chỉ là ...
Number(42).toString(2);
// "101010"
(42).toString(2)
42..toString(2)
1.
giống 1.0
hoặc chỉ 1
(và tương tự bạn cũng có thể bỏ qua phần trước và viết .5
thay vì 0.5
). Vì vậy, trong ví dụ, dấu chấm đầu tiên là dấu tách thập phân là một phần của số và dấu chấm thứ hai là toán tử dấu chấm để gọi phương thức trên số đó. Bạn phải sử dụng hai dấu chấm (hoặc bọc số trong ngoặc đơn) và không thể chỉ viết 42.toString(2)
vì trình phân tích cú pháp xem dấu chấm là dấu phân cách thập phân và đưa ra lỗi do thiếu toán tử dấu chấm.
Câu trả lời này cố gắng giải quyết các đầu vào có giá trị tuyệt đối trong phạm vi 2147483648 10 (2 31 ) - 9007199254740991 10 (2 53 -1).
Trong JavaScript, các số được lưu trữ trong biểu diễn dấu phẩy động 64 bit , nhưng các thao tác bitwise buộc chúng thành các số nguyên 32 bit ở định dạng bổ sung hai , do đó, bất kỳ cách tiếp cận nào sử dụng các thao tác bitwise đều giới hạn phạm vi đầu ra ở -2147483648 10 (-2 31 ) - 2147483647 10 (2 31 -1).
Tuy nhiên, nếu tránh các thao tác bitwise và biểu diễn dấu phẩy động 64 bit được bảo toàn bằng cách chỉ sử dụng các phép toán, chúng ta có thể chuyển đổi một cách đáng tin cậy bất kỳ số nguyên an toàn nào thành ký hiệu nhị phân bổ sung hai bit 64 bit bằng cách mở rộng ký hiệu 53 bit 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}
Đối với các trình duyệt cũ hơn, polyfill tồn tại cho các hàm và giá trị sau:
Là một phần thưởng bổ sung, bạn có thể hỗ trợ bất kỳ cơ số nào (2 Pha36) nếu bạn thực hiện chuyển đổi bổ sung của hai số cho các số âm ở ⌈64 / log 2 (cơ số) ⌉ bằng cách sử dụng 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}
Nếu bạn quan tâm đến câu trả lời cũ của tôi đã sử dụng một ArrayBuffer
để tạo sự kết hợp giữa a Float64Array
và a Uint16Array
, vui lòng tham khảo lịch sử sửa đổi của câu trả lời này .
-(2**53)-1
đến 2**53-1
thay vì chỉ -(2**31)
để 2**31-1
như câu trả lời của Annan.
Một giải pháp tôi phù hợp với điều đó là tốt cho 32 bit, là đoạn mã kết thúc câu trả lời này, từ developer.mozilla.org (MDN), nhưng với một số dòng được thêm vào định dạng A) và B) kiểm tra xem số là trong phạm vi.
Một số gợi ý x.toString(2)
không hoạt động cho tiêu cực, nó chỉ đưa ra một dấu trừ trong đó cho họ, điều này là không tốt.
Fernando đã đề cập đến một giải pháp đơn giản trong (x>>>0).toString(2);
đó là tốt cho tiêu cực, nhưng có một vấn đề nhỏ khi x là tích cực. Nó có đầu ra bắt đầu bằng 1, mà đối với các số dương không phải là bổ sung 2s thích hợp.
Bất kỳ ai không hiểu thực tế về số dương bắt đầu bằng 0 và số âm với 1, trong 2 giây, có thể kiểm tra SO QnA này trên phần bù 2 giây. Bổ sung là gì?
Một giải pháp có thể liên quan đến việc trả trước 0 cho các số dương, điều mà tôi đã làm trong lần sửa đổi trước của câu trả lời này. Và người ta có thể chấp nhận đôi khi có số 33 bit hoặc người ta có thể chắc chắn rằng số cần chuyển đổi nằm trong phạm vi - (2 ^ 31) <= x <2 ^ 31-1. Vì vậy, số lượng luôn luôn là 32 bit. Nhưng thay vì làm điều đó, bạn có thể đi với giải pháp này trên mozilla.org
Câu trả lời và mã của Patrick dài và rõ ràng hoạt động trong 64 bit, nhưng có một lỗi mà một người bình luận đã tìm thấy, và người bình luận đã sửa lỗi của patrick, nhưng patrick có một số "số ma thuật" trong mã mà anh ta không bình luận và có quên về và patrick không còn hiểu đầy đủ mã của riêng mình / tại sao nó hoạt động.
Annan có một số thuật ngữ không chính xác và không rõ ràng nhưng đã đề cập đến một giải pháp của developer.mozilla.org https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators Công cụ này hoạt động với các số 32 bit.
Mã này khá nhỏ gọn, một chức năng của ba dòng.
Nhưng tôi đã thêm một regex để định dạng đầu ra theo nhóm 8 bit. Dựa trên Cách in một số bằng dấu phẩy dưới dạng hàng nghìn dấu phân cách trong JavaScript (Tôi chỉ sửa đổi nó từ việc nhóm nó trong 3 giây từ phải sang trái và thêm dấu phẩy , để nhóm trong 8 giây từ phải sang trái và thêm khoảng trắng )
Và, trong khi mozilla đưa ra nhận xét về kích thước của nMask (số lượng được cung cấp) .. nó phải nằm trong phạm vi, họ đã không kiểm tra hoặc ném lỗi khi số nằm ngoài phạm vi, vì vậy tôi đã nói thêm rằng
Tôi không chắc tại sao họ đặt tên cho tham số của họ là 'nMask' nhưng tôi sẽ để nguyên như vậy.
Tham khảo: 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"
Bạn có thể viết hàm riêng của mình trả về một mảng bit. Ví dụ cách chuyển đổi số thành bit
ví dụ về dòng trên: 2 * 4 = 8 và phần còn lại là 1 nên 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
}
Đọc phần còn lại từ dưới lên trên. Chữ số 1 ở giữa lên trên.
Math.floor(number%2)
thay vì number = Math.floor(number/2)
?
Tôi đã sử dụng một cách tiếp cận khác nhau để đưa ra một cái gì đó làm điều này. Tôi đã quyết định không sử dụng mã này trong dự án của mình, nhưng tôi nghĩ rằng tôi đã để nó ở đâu đó có liên quan trong trường hợp nó hữu ích cho ai đó.
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("---");
Thêm một sự thay thế
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));
Đây là mã của tôi:
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();
Đây là giải pháp. Nó khá đơn giản như một vấn đề thực tế
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.
*/