İkili olarak pozitif veya negatif tamsayıları görmek istiyorum.
Bu soru gibi , ama JavaScript için.
İkili olarak pozitif veya negatif tamsayıları görmek istiyorum.
Bu soru gibi , ama JavaScript için.
Yanıtlar:
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
dec2bin(1); // 1
dec2bin(-1); // 11111111111111111111111111111111
dec2bin(256); // 100000000
dec2bin(-256); // 11111111111111111111111100000000
Number.toString(2)İşlevi kullanabilirsiniz , ancak negatif sayıları temsil ederken bazı sorunları vardır. Örneğin, (-1).toString(2)çıktı "-1".
Bu sorunu gidermek için, imzasız sağ kaydırma bitsel operatörünü ( >>>) kullanarak numaranızı imzasız bir tam sayıya zorlayabilirsiniz.
Çalıştırırsanız (-1 >>> 0).toString(2), 0 bitinizi sağa kaydırırsınız, bu sayının kendisini değiştirmez, ancak işaretsiz bir tamsayı olarak temsil edilir. Yukarıdaki kod "11111111111111111111111111111111"düzgün çıkacaktır .
Bu sorunun daha fazla açıklaması var.
-3 >>> 0(sağ mantıksal kaydırma) argümanlarını işaretsiz tamsayılara zorlar, bu nedenle 32 bit ikisinin -3 tamamlayıcı gösterimini alırsınız.
Deneyin
num.toString(2);
2 yarıçaptır ve 2 ile 36 arasında herhangi bir taban olabilir
burada kaynak
GÜNCELLEME:
Bu sadece pozitif sayılar için işe yarayacaktır, Javascript ikinin tamamlayıcı gösterimindeki negatif ikili tam sayıları temsil etmektedir. Hile yapması gereken bu küçük işlevi yaptım, düzgün bir şekilde test etmedim:
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);
}
}
Buradan biraz yardım aldım
-3iadeler 1) için çalışmıyor gibi görünüyor . Ayrıca inanıyorum dec > 0olmalı dec >= 0ki gereken asgari düzeltme 0. az olduğundan, dec2Bin(0)döner 10.
'İkili dosyaya dönüştür' içindeki ikili dosya üç ana şeye işaret edebilir. Konumsal sayı sistemi, bellekteki ikili gösterim veya 32 bit bit dizileri. (64 bitlik bit dizileri için bkz. Patrick Roberts'ın cevabı )
1. Sayı Sistemi
(123456).toString(2)sayıları temel 2 konumsal sayısal sisteme dönüştürür . Bu sistemde negatif sayılar tıpkı ondalık basamaktaki gibi eksi işaretleri ile yazılır.
2. Dahili Temsil
Sayıların iç temsili 64 bit kayan noktadır ve bu cevapta bazı sınırlamalar tartışılmıştır . Orada kolay bir yolu javascript ne de erişim belirli bit bu biraz-string gösterimini oluşturmak için.
3. Maskeler ve Bitsel Operatörler
MDN, operatörlerin nasıl çalıştığına dair iyi bir genel bakışa sahiptir . Önemli:
Bitsel operatörler, işlenenlerini 32 bitlik bir dizi (sıfırlar ve olanlar) olarak ele alır
İşlemler uygulanmadan önce 64 bit kayan nokta sayıları 32 bit işaretli tam sayılara verilir. Geri dönüştürüldükten sonra.
Sayıları 32 bit dizelere dönüştürmek için kullanılan MDN örnek kodu.
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"
Basit bir yol ...
Number(42).toString(2);
// "101010"
(42).toString(2)
42..toString(2)
1.Aynı 1.0veya sadece aynı olanı yazabilirsiniz 1(ve benzer şekilde parçayı daha önce atlayabilir ve .5bunun yerine yazabilirsiniz 0.5). Dolayısıyla örnekte ilk nokta, sayının bir parçası olan ondalık ayırıcı ve ikinci nokta, bu sayıdaki yöntemi çağırmak için nokta operatörüdür. İki nokta kullanmanız (veya sayıyı parantez içine almanız) ve 42.toString(2)ayrıştırıcı noktayı ondalık ayırıcı olarak gördüğünden ve eksik nokta işleci nedeniyle bir hata attığından yazamazsınız .
Bu cevap, 2147483648 10 (2 31 ) - 9007199254740991 10 (2 53 -1) aralığında mutlak değeri olan girdileri ele almaya çalışır .
JavaScript, numaralar saklanır 64 bit kayan nokta gösterimi , ancak 32-bit tamsayı bunları bit seviyesinde işlemler zorlamak içinde ikinin tamamlayıcı biçiminde bit düzeyinde işlemleri kullanan herhangi bir yaklaşım -2147483648 çıktı aralığını kısıtlar, böylece 10 (-2 31 ) - 2147483647 10 (2 31 -1).
Ancak, bitsel işlemlerden kaçınılırsa ve 64-bit kayan nokta gösterimi yalnızca matematiksel işlemler kullanılarak korunursa, 53-bit işaretini genişleterek herhangi bir güvenli tamsayıyı 64-bit ikinin tamamlayıcı ikili gösterimine güvenilir bir şekilde dönüştürebiliriz 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}
Daha eski tarayıcılarda, aşağıdaki işlevler ve değerler için çoklu dolgular mevcuttur:
Ek bir bonus olarak, ⌈64 / log 2 (radix) ⌉ rakamlarında negatif sayılar için ikisinin tamamlayıcı dönüşümünü gerçekleştirirseniz, herhangi bir yarıçapı (2-36) destekleyebilirsiniz 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}
ArrayBufferA Float64Arrayile a arasında bir birlik oluşturmak için a kullanılan eski yanıtımla ilgileniyorsanız Uint16Array, lütfen bu yanıtın düzeltme geçmişine bakın .
-(2**53)-1için 2**53-1yerine sadece -(2**31)üzere 2**31-1Annan cevap gibi.
Ben 32 bit için bu iyi gider bir çözüm geliştirici.mozilla.org (MDN), ancak A) biçimlendirme ve B) bazı satırlar ekleyerek bu cevabın sonu kodudur sayı aralık dahilinde.
Bazıları x.toString(2)negatifler için işe yaramaz önerdi , sadece onlar için orada bir eksi işareti yapışıyor, bu iyi değil.
Fernando (x>>>0).toString(2);, negatifler için iyi, ancak x pozitif olduğunda küçük bir sorunu olan basit bir çözümden bahsetti . Çıktı 1 ile başlayan, pozitif sayılar için uygun 2s tamamlayıcı değil.
0 ile başlayan pozitif sayılar ve 2s tamamlayıcıda 1 ile negatif sayılar gerçeğini anlamayan herkes, 2s tamamlayıcısında bu SO QnA'yı kontrol edebilir. “2'nin Tamamlayıcısı” nedir?
Bir çözüm, bu sayının daha önceki bir revizyonunda yaptığım pozitif sayılar için 0 eklemeyi içerebilir. Ve bazen 33 bitlik bir sayıya sahip olabilir veya dönüştürülecek sayının aralık içinde olduğundan emin olabilir - (2 ^ 31) <= x <2 ^ 31-1. Yani sayı her zaman 32 bittir. Ancak bunu yapmak yerine, bu çözümle mozilla.org'da gidebilirsiniz.
Patrick'in cevabı ve kodu uzun ve görünüşe göre 64 bit için çalışıyor, ancak bir yorumcunun bulduğu bir hata vardı ve yorumcu patrick'nin hatasını düzeltti, ancak patrick kodunda yorum yapmadığı ve sahip olmadığı bir "sihirli sayı" var unutulmuş ve patrick artık kendi kodunu / neden işe yaradığını tam olarak anlayamıyor.
Annan'ın yanlış ve belirsiz bir terminolojisi vardı, ancak developer.mozilla.org tarafından bir çözümden bahsetti https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators Bu 32-bit sayılar için çalışır.
Kod oldukça kompakt, üç satırlık bir işlev.
Ancak çıktıyı 8 bitlik gruplar halinde biçimlendirmek için bir normal ifade ekledim. JavaScript'te binlik ayırıcı olarak virgül içeren bir sayının nasıl yazdırılacağı temel alınmıştır (Sadece bunu gruplandırma onu tadil 3s sağdan sola ve eklemenin virgül gruplama için, 8s sağdan sola ve ekleme boşluk )
Ve, mozilla nMask'ın boyutu (beslenen sayı) hakkında bir yorum yaparken, aralıkta olması gerektiği gibi, sayı aralık dışında olduğunda test etmediler veya bir hata atmadılar, bu yüzden ekledi.
Neden onların parametre 'nMask' adlı emin değilim ama olduğu gibi bırakacağım.
Referans: 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"
Bir dizi bit döndüren kendi işlevinizi yazabilirsiniz. Sayıyı bitlere dönüştürme örneği
yukarıdaki satır örneği: 2 * 4 = 8 ve kalan 1 1 yani 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
}
Kalanları aşağıdan yukarıya doğru okuyun. Rakam 1 ortada üstte.
Math.floor(number%2)yerine number = Math.floor(number/2)?
Bunu yapan bir şey bulmak için farklı bir yaklaşım kullandım. Bu kodu projemde kullanmamaya karar verdim, ancak birisi için yararlı olması durumunda ilgili bir yerde bırakacağımı düşündüm.
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("---");
Bir alternatif daha
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));
Bu benim kodum:
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();
Bu çözüm. Aslına bakarsanız oldukça basit
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.
*/