Saya ingin melihat bilangan bulat, positif atau negatif, dalam biner.
Agak suka pertanyaan ini , tapi untuk JavaScript.
Saya ingin melihat bilangan bulat, positif atau negatif, dalam biner.
Agak suka pertanyaan ini , tapi untuk JavaScript.
Jawaban:
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
dec2bin(1); // 1
dec2bin(-1); // 11111111111111111111111111111111
dec2bin(256); // 100000000
dec2bin(-256); // 11111111111111111111111100000000
Anda dapat menggunakan Number.toString(2)
fungsi, tetapi memiliki beberapa masalah saat merepresentasikan angka negatif. Misalnya, (-1).toString(2)
output "-1"
.
Untuk memperbaiki masalah ini, Anda dapat menggunakan operator bitwise pergeseran kanan yang tidak ditandatangani ( >>>
) untuk memaksa nomor Anda ke integer yang tidak ditandatangani.
Jika Anda menjalankan, (-1 >>> 0).toString(2)
Anda akan menggeser angka 0 bit Anda ke kanan, yang tidak mengubah angka itu sendiri tetapi akan diwakili sebagai bilangan bulat yang tidak ditandatangani. Kode di atas akan menampilkan "11111111111111111111111111111111"
dengan benar.
Pertanyaan ini memiliki penjelasan lebih lanjut.
-3 >>> 0
(Pergeseran logis kanan) memaksakan argumennya ke integer yang tidak ditandai, itulah sebabnya Anda mendapatkan representasi komplemen 32-bit two dari -3.
Mencoba
num.toString(2);
2 adalah radix dan dapat berupa basis antara 2 dan 36
sumber di sini
MEMPERBARUI:
Ini hanya akan berfungsi untuk angka positif, Javascript mewakili bilangan bulat biner negatif dalam notasi dua komplemen. Saya membuat fungsi kecil ini yang seharusnya melakukan trik, saya belum mengujinya dengan benar:
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);
}
}
Saya mendapat bantuan dari sini
-3
pengembalian 1
). Saya juga percaya dec > 0
harus dec >= 0
, yang setidaknya harus memperbaiki 0. Karena dec2Bin(0)
pengembalian 10
.
Biner dalam 'convert to binary' dapat merujuk pada tiga hal utama. Sistem angka posisi, representasi biner dalam memori atau bitstring 32bit. (untuk 64 bit bitstring lihat jawaban Patrick Roberts )
1. Sistem Angka
(123456).toString(2)
akan mengonversi angka ke sistem angka posisi dasar 2 . Dalam sistem ini angka negatif ditulis dengan tanda minus seperti dalam desimal.
2. Representasi Internal
Representasi internal angka adalah floating point 64 bit dan beberapa batasan dibahas dalam jawaban ini . Tidak ada cara mudah untuk membuat representasi bit-string ini dalam javascript atau mengakses bit tertentu.
3. Operator Masker & Bitwise
MDN memiliki tinjauan yang baik tentang bagaimana operator bitwise bekerja. Penting:
Operator bitwise memperlakukan operan mereka sebagai urutan 32 bit (nol dan satu)
Sebelum operasi diterapkan, angka floating point 64 bit dilemparkan ke bilangan bulat bertanda 32 bit. Setelah mereka bertobat kembali.
Berikut adalah contoh kode MDN untuk mengubah angka menjadi string 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"
Cara sederhana hanya ...
Number(42).toString(2);
// "101010"
(42).toString(2)
42..toString(2)
1.
yang sama dengan 1.0
atau hanya 1
(dan Anda juga dapat menghilangkan bagian sebelumnya dan menulis .5
bukan 0.5
). Jadi dalam contoh titik pertama adalah pemisah desimal yang merupakan bagian dari angka dan titik kedua adalah operator titik untuk memanggil metode pada nomor itu. Anda harus menggunakan dua titik (atau membungkus angka dalam tanda kurung) dan tidak bisa hanya menulis 42.toString(2)
karena parser melihat titik sebagai pemisah desimal dan melempar kesalahan karena operator titik yang hilang.
Jawaban ini mencoba menangani input dengan nilai absolut di kisaran 2147483648 10 (2 31 ) - 9007199254740991 10 (2 53 -1).
Dalam JavaScript, angka disimpan dalam representasi titik mengambang 64-bit , tetapi operasi bitwise memaksa mereka ke bilangan bulat 32-bit dalam format komplemen dua , sehingga pendekatan apa pun yang menggunakan operasi bitwise membatasi rentang output ke -2147483648 10 (-2 31 ) - 2147483647 10 (2 31 -1).
Namun, jika operasi bitwise dihindari dan representasi floating point 64-bit dipertahankan dengan hanya menggunakan operasi matematika, kita dapat secara andal mengonversi bilangan bulat aman apa pun ke notasi biner komplemen 64-bit dua dengan menandatangani perpanjangan 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}
Untuk browser lama, polyfill ada untuk fungsi dan nilai berikut:
Sebagai bonus tambahan, Anda dapat mendukung semua radix (2–36) jika Anda melakukan konversi komplemen keduanya untuk angka negatif di ⌈64 / log 2 (radix) ⌉ digit dengan menggunakan 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}
Jika Anda tertarik dengan jawaban lama saya yang menggunakan a ArrayBuffer
untuk membuat gabungan antara a Float64Array
dan a Uint16Array
, silakan merujuk ke riwayat revisi jawaban ini .
-(2**53)-1
untuk 2**53-1
bukan hanya -(2**31)
untuk 2**31-1
seperti jawaban annan ini.
Solusi yang saya gunakan untuk 32-bit, adalah kode akhir dari jawaban ini, yaitu dari developer.mozilla.org (MDN), tetapi dengan beberapa baris ditambahkan untuk A) pemformatan dan B) memeriksa bahwa nomor dalam jangkauan.
Beberapa menyarankan x.toString(2)
yang tidak bekerja untuk negatif, itu hanya menempel tanda minus di sana untuk mereka, yang tidak baik.
Fernando menyebutkan solusi sederhana (x>>>0).toString(2);
yang baik untuk negatif, tetapi memiliki sedikit masalah ketika x positif. Ini memiliki output dimulai dengan 1, yang untuk bilangan positif tidak melengkapi 2s tepat.
Siapa pun yang tidak memahami fakta angka positif dimulai dengan 0 dan angka negatif dengan 1, dalam komplemen 2s, dapat memeriksa SO QnA ini pada komplemen 2s. Apa itu "Komplemen 2"?
Sebuah solusi dapat melibatkan menambahkan 0 untuk angka positif, yang saya lakukan dalam revisi sebelumnya dari jawaban ini. Dan seseorang dapat menerima kadang-kadang memiliki nomor 33bit, atau seseorang dapat memastikan bahwa nomor yang dikonversi berada dalam kisaran - (2 ^ 31) <= x <2 ^ 31-1. Jadi jumlahnya selalu 32 bit. Tapi daripada melakukannya, Anda bisa menggunakan solusi ini di mozilla.org
Jawaban dan kode Patrick panjang dan tampaknya berfungsi untuk 64-bit, tetapi memiliki bug yang ditemukan oleh seorang komentator, dan komentator memperbaiki bug patrick, tetapi patrick memiliki beberapa "angka ajaib" dalam kode yang tidak dikomentari dan memiliki dilupakan dan patrick tidak lagi sepenuhnya memahami kodenya sendiri / mengapa itu bekerja.
Annan memiliki beberapa terminologi yang salah dan tidak jelas tetapi menyebutkan solusi oleh developer.mozilla.org https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators Ini berfungsi untuk angka 32-bit.
Kode ini cukup kompak, fungsi dari tiga baris.
Tapi saya telah menambahkan regex untuk memformat output dalam kelompok 8 bit. Berdasarkan Cara mencetak angka dengan koma sebagai ribuan pemisah dalam JavaScript (Saya baru saja mengubahnya dari mengelompokkannya menjadi 3s ke kanan dan menambahkan koma , menjadi pengelompokan dalam 8s dari kanan ke kiri, dan menambahkan spasi )
Dan, sementara mozilla membuat komentar tentang ukuran nMask (jumlah yang dimasukkan) .. bahwa itu harus dalam jangkauan, mereka tidak menguji atau melempar kesalahan ketika jumlahnya di luar jangkauan, jadi saya sudah menambahkan itu.
Saya tidak yakin mengapa mereka menamai parameter mereka 'nMask' tetapi saya akan membiarkannya apa adanya.
Referensi: 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"
Anda dapat menulis fungsi Anda sendiri yang mengembalikan array bit. Contoh cara mengonversi angka menjadi bit
contoh baris di atas: 2 * 4 = 8 dan sisanya adalah 1 jadi 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
}
Baca sisa dari bawah ke atas. Angka 1 di tengah ke atas.
Math.floor(number%2)
bukan number = Math.floor(number/2)
?
Saya menggunakan pendekatan yang berbeda untuk menghasilkan sesuatu yang melakukan ini. Saya memutuskan untuk tidak menggunakan kode ini dalam proyek saya, tetapi saya pikir saya akan meninggalkannya di tempat yang relevan jika berguna bagi seseorang.
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("---");
Satu lagi alternatif
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));
Ini kode saya:
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();
Ini solusinya. Sebenarnya cukup sederhana
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.
*/