Chciałbym zobaczyć liczby całkowite, dodatnie lub ujemne, w postaci binarnej.
Raczej jak to pytanie , ale dla JavaScript.
Chciałbym zobaczyć liczby całkowite, dodatnie lub ujemne, w postaci binarnej.
Raczej jak to pytanie , ale dla JavaScript.
Odpowiedzi:
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
dec2bin(1); // 1
dec2bin(-1); // 11111111111111111111111111111111
dec2bin(256); // 100000000
dec2bin(-256); // 11111111111111111111111100000000
Możesz użyć Number.toString(2)
funkcji, ale ma ona pewne problemy przy reprezentowaniu liczb ujemnych. Na przykład (-1).toString(2)
dane wyjściowe to "-1"
.
Aby rozwiązać ten problem, możesz użyć niepodpisanego operatora bitowego przesunięcia w prawo (>>>
), aby zmusić swój numer do liczby całkowitej bez znaku.
Jeśli uruchomisz (-1 >>> 0).toString(2)
, przeniesiesz bity cyfry 0 w prawo, co nie zmienia samej liczby, ale będzie reprezentowane jako liczba całkowita bez znaku. Powyższy kod wyświetli się "11111111111111111111111111111111"
poprawnie.
To pytanie zawiera dalsze wyjaśnienia.
-3 >>> 0
(prawe przesunięcie logiczne) wymusza argumenty na liczbach całkowitych bez znaku, dlatego otrzymujemy 32-bitową reprezentację uzupełnienia dwóch -3.
Próbować
num.toString(2);
2 to podstawa i może być dowolną bazą między 2 a 36
źródło tutaj
AKTUALIZACJA:
Działa to tylko w przypadku liczb dodatnich, JavaScript reprezentuje ujemne binarne liczby całkowite w notacji dwóch uzupełnień. Zrobiłem tę małą funkcję, która powinna załatwić sprawę, nie przetestowałem jej poprawnie:
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);
}
}
Miałem stąd pomoc
-3
zwrotów 1
). Też uważam, że dec > 0
powinien być dec >= 0
, który powinien przynajmniej naprawić 0. Ponieważ dec2Bin(0)
zwraca 10
.
Plik binarny w „Convert to binary” może odnosić się do trzech głównych rzeczy. System liczb pozycyjnych, reprezentacja binarna w pamięci lub 32-bitowe ciągi bitów. (w przypadku 64-bitowych ciągów bitów patrz odpowiedź Patricka Robertsa )
1. System liczbowy
(123456).toString(2)
przekształci liczby w podstawowy system liczb pozycyjnych 2 . W tym systemie liczby ujemne są zapisywane ze znakami minusowymi, tak jak w systemie dziesiętnym.
2. Przedstawicielstwo wewnętrzne
Wewnętrzna reprezentacja liczb jest zmiennoprzecinkowa 64-bitowa i niektóre ograniczenia są omówione w tej odpowiedzi . Nie ma łatwego sposobu na utworzenie tego ciągu bitowego w javascript ani dostęp do określonych bitów.
3. Maski i operatory bitowe
MDN ma dobry przegląd działania operatorów bitowych. Co ważne:
Operatory bitowe traktują swoje operandy jako ciąg 32 bitów (zer i jedynek)
Przed zastosowaniem operacji 64-bitowe liczby zmiennoprzecinkowe są rzutowane na 32-bitowe liczby całkowite ze znakiem. Po ich ponownej konwersji.
Oto przykładowy kod MDN do konwersji liczb na ciągi 32-bitowe.
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"
Prostym sposobem jest po prostu ...
Number(42).toString(2);
// "101010"
(42).toString(2)
42..toString(2)
1.
tak samo jak 1.0
lub tylko 1
(i podobnie możesz także pominąć część przed i pisać .5
zamiast 0.5
). Tak więc w tym przykładzie pierwsza kropka jest separatorem dziesiętnym, który jest częścią liczby, a druga kropka jest operatorem kropki służącym do wywołania metody na tym numerze. Musisz użyć dwóch kropek (lub owinąć liczbę w nawiasach) i nie możesz po prostu pisać, 42.toString(2)
ponieważ parser widzi kropkę jako separator dziesiętny i zgłasza błąd z powodu braku operatora kropki.
Ta odpowiedź próbuje adresować dane wejściowe o wartości bezwzględnej w zakresie 2147483648 10 (2 31 ) - 9007199254740991 10 (2 53 -1).
W JavaScript liczby są przechowywane w 64-bitowej reprezentacji zmiennoprzecinkowej , ale operacje bitowe zmuszają je do 32-bitowych liczb całkowitych w formacie uzupełnienia do dwóch , więc każde podejście wykorzystujące operacje bitowe ogranicza zakres wyniku do -2147483648 10 (-2 31 ) - 2147483647 10 (2 31 -1).
Jeśli jednak uniknie się operacji bitowych, a 64-bitowa reprezentacja zmiennoprzecinkowa zostanie zachowana przy użyciu tylko operacji matematycznych, możemy niezawodnie przekonwertować dowolną bezpieczną liczbę całkowitą na 64-bitową dopełniającą notację binarną z dopełnieniem 53-bitowego znaku 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}
W starszych przeglądarkach istnieją wielopełniacze następujących funkcji i wartości:
Jako dodatkowy bonus możesz wesprzeć dowolny podstawnik (2–36), jeśli wykonasz konwersję uzupełnienia dwóch liczb ujemnych w liczbach ⌈64 / log 2 (podstawa) ⌉ przy użyciu 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}
Jeśli jesteś zainteresowany moją starą odpowiedzią, która posłużyła ArrayBuffer
do utworzenia związku między a, Float64Array
a Uint16Array
zapoznaj się z historią wersji tej odpowiedzi .
-(2**53)-1
celu 2**53-1
, a nie tylko -(2**31)
do 2**31-1
jak odpowiedź Annana.
Rozwiązaniem, które wybrałbym w porządku dla 32-bitów, jest kod na końcu tej odpowiedzi, który pochodzi z developer.mozilla.org (MDN), ale z pewnymi wierszami dodanymi do A) formatowania i B) sprawdzania, czy liczba jest w zakresie.
Niektórzy sugerowali x.toString(2)
że nie działa na negatywy, po prostu umieszcza tam znak minus, co nie jest dobre.
Fernando wspomniał o prostym rozwiązaniu (x>>>0).toString(2);
które jest odpowiednie dla negatywów, ale ma niewielki problem, gdy x jest dodatnie. Ma wyjście zaczynające się od 1, co dla liczb dodatnich nie jest właściwym uzupełnieniem 2s.
Każdy, kto nie rozumie faktu, że liczby dodatnie zaczynają się od 0 i liczby ujemne z 1, w uzupełnieniu 2s, może sprawdzić tę SO QnA w uzupełnieniu 2s. Co to jest „Uzupełnienie 2”?
Rozwiązaniem mogłoby być wcześniejsze wpisanie 0 dla liczb dodatnich, co zrobiłem we wcześniejszej wersji tej odpowiedzi. Czasami można zaakceptować liczbę 33-bitową lub upewnić się, że liczba do konwersji mieści się w zakresie - (2 ^ 31) <= x <2 ^ 31-1. Tak więc liczba wynosi zawsze 32 bity. Ale zamiast tego możesz skorzystać z tego rozwiązania na mozilla.org
Odpowiedź i kod Patryka jest długi i najwyraźniej działa na 64-bit, ale miał błąd znaleziony przez komentatora, a komentator naprawił błąd patryka, ale patrick ma w swoim kodzie „magiczną liczbę”, o której nie skomentował i zapomniany i Patrick nie rozumie już w pełni własnego kodu / dlaczego on działa.
Annan miał niepoprawną i niejasną terminologię, ale wspomniał o rozwiązaniu autorstwa developer.mozilla.org https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators Działa to dla liczb 32-bitowych.
Kod jest dość kompaktowy, funkcja trzech wierszy.
Ale dodałem wyrażenie regularne, aby sformatować dane wyjściowe w grupach po 8 bitów. Oparty na tym, jak wydrukować liczbę z przecinkami jako tysiące separatorów w JavaScript (właśnie zmieniłem ją od zgrupowania jej w 3s od prawej do lewej i dodawania przecinków , do grupowania w 8s od prawej do lewej i dodania spacji )
I chociaż Mozilla skomentowała rozmiar nMaski (liczby wprowadzonej) .. że musi on znajdować się w zakresie, nie testowali ani nie zgłaszali błędu, gdy liczba jest poza zakresem, więc mam dodał to.
Nie jestem pewien, dlaczego nazwali swój parametr „nMask”, ale pozostawię to bez zmian.
Odniesienie: 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"
Możesz napisać własną funkcję, która zwraca tablicę bitów. Przykład jak przekonwertować liczbę na bity
przykład powyższej linii: 2 * 4 = 8, a reszta to 1, więc 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
}
Czytaj resztki od dołu do góry. Cyfra 1 od środka do góry.
Math.floor(number%2)
zamiast tego number = Math.floor(number/2)
?
Użyłem innego podejścia, aby wymyślić coś, co to robi. Zdecydowałem się nie używać tego kodu w moim projekcie, ale pomyślałem, że zostawię go gdzieś istotnym na wypadek, gdyby był przydatny dla kogoś.
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("---");
Jeszcze jedna alternatywa
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));
To jest mój kod:
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();
To jest rozwiązanie. Jest to dość proste
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.
*/