Czy istnieje „0b” lub coś podobnego, które reprezentuje liczbę binarną w JavaScript

130

Wiem, że 0xjest to prefiks dla liczb szesnastkowych w JavaScript. Na przykład 0xFFoznacza liczbę 255.

Czy jest coś podobnego do liczb binarnych? Spodziewałbym się, że będę 0b1111reprezentował liczbę 15, ale to nie działa dla mnie.

Misha Moroshko
źródło
1
Z ciekawości: Dlaczego potrzebujesz literałów binarnych w Javascript? Wysokopoziomowy charakter Javascript oznacza, że ​​zwykle nie wymaga on interakcji z konstrukcjami niskiego poziomu, które wymagałyby literałów binarnych.
Joachim Sauer
19
Ponieważ w ten sposób kod będzie bardziej czytelny. Moja implementacja jest oparta na specyfikacji, która używa liczb binarnych.
Misha Moroshko
5
użycie node js do robotyki jest dobrym przykładem tego, gdzie może być wymagany plik binarny
Greg Woods
Możesz rozważyć użycie separatorów numerycznych dla lepszej czytelności. 0b0111_0_1_0_1.
Константин Ван

Odpowiedzi:

181

Aktualizacja:

Nowsze wersje JavaScript - w szczególności ECMAScript 6 - dodały obsługę literałów liczbowych binarnych (prefiks 0b), ósemkowych (prefiks 0o) i szesnastkowych (prefiks 0x:):

var bin = 0b1111;    // bin will be set to 15
var oct = 0o17;      // oct will be set to 15
var oxx = 017;       // oxx will be set to 15
var hex = 0xF;       // hex will be set to 15
// note: bB oO xX are all valid

Ta funkcja jest już dostępna w przeglądarkach Firefox i Chrome. Obecnie nie jest obsługiwany w IE, ale najwyraźniej będzie, gdy pojawi się Spartan.

(Dzięki średnik komentarzu „s i odpowiedzi urish koszulka dla wskazujące na to.)

Oryginalna odpowiedź:

Nie, nie ma odpowiednika dla liczb binarnych. JavaScript obsługuje tylko literały numeryczne w formacie dziesiętnym (bez przedrostka), szesnastkowym (przedrostek 0x) i ósemkowym (przedrostek 0).

Jedną z możliwych alternatyw jest przekazanie ciągu binarnego do parseIntmetody wraz z podstawą:

var foo = parseInt('1111', 2);    // foo will be set to 15
LukeH
źródło
2
@MishaMoroshko Zgadzam się, ale kilka języków ma 0bwsparcie.
Alba Mendez,
5
Technicznie rzecz biorąc, JavaScript nie obsługuje notacji ósemkowej, chociaż większość (wszystkie?) Przeglądarki ją obsługują. Jest to wyraźnie zabronione w trybie ścisłym.
Deebster
5
Zauważ, że wewnętrznie w JavaScript każda liczba jest 64-bitową liczbą zmiennoprzecinkową, nie ma czegoś takiego jak liczba całkowita. W ten sposób przy dużych liczbach tracisz dokładność. Największa dokładna liczba całkowita to 2 ^ 53, czyli 9007199254740992.
zupa Kwietnia
5
Istnieją liczby całkowite, ponieważ liczba całkowita jest terminem matematycznym, nie ma int typeani integer type, więc wszystkie liczby całkowite są przechowywane jako liczby zmiennoprzecinkowe .
Perkins,
3
W tamtym czasie ta odpowiedź była prawdziwa, ale przydałaby się aktualizacja. Jak podkreśla Urish w swojej odpowiedzi poniżej, w ES6 znajdują się literały liczb binarnych i ósemkowych (ósemki są teraz zapisywane jako „0o1”). Wylądowali już w Firefoksie, Chrome, a nawet w wersji zapoznawczej nowego IE (Spartan).
Średnik
29

W ECMASCript 6 będzie to obsługiwane jako część języka, tj. 0b1111 === 15Jest prawdziwe. Możesz także użyć dużej litery B (np 0B1111.).

Szukaj NumericLiteralsw specyfikacji ES6 .

urish
źródło
23

Wiem, że ludzie mówią, że rozbudowa prototypów to nie jest dobry pomysł, ale taki był twój scenariusz ...

Robię to w ten sposób:

Object.defineProperty(Number.prototype, 'b', {set:function(){return false;},get:function(){return parseInt(this, 2);}});

100..b       // returns 4
11111111..b  // returns 511
10..b+1      // returns 3

// and so on
Juan Garcia
źródło
3
To jest fajne! 8-) Zauważ, że ParseInt("101", 2)może to być właściwa odpowiedź!
Alexis Wilke
20

Jeśli Twoim głównym problemem jest wyświetlanie, a nie kodowanie, istnieje wbudowany system konwersji, którego możesz użyć:

var num = 255;
document.writeln(num.toString(16)); // Outputs: "ff"
document.writeln(num.toString(8)); // Outputs: "377"
document.writeln(num.toString(2)); // Outputs: "11111111"

Ref: Numer JavaScript

Wyskakuje
źródło
11

O ile wiem, w Javascript nie można używać binarnego denotera. Mam dla ciebie trzy rozwiązania, z których wszystkie mają swoje problemy. Myślę, że alternatywa 3 jest najbardziej „ładna” pod względem czytelności i prawdopodobnie jest znacznie szybsza niż reszta - z wyjątkiem początkowego kosztu czasu wykonania. Problem w tym, że obsługuje tylko wartości do 255.

Alternatywa 1: "00001111".b()

String.prototype.b = function() { return parseInt(this,2); }

Alternatywa 2: b("00001111")

function b(i) { if(typeof i=='string') return parseInt(i,2); throw "Expects string"; }

Alternatywa 3: b00001111

Ta wersja umożliwia wpisanie 8 cyfr binarnych b00000000, 4 cyfrowych b0000i zmiennych b0. To jest b01nielegalne, musisz użyć b0001lub b1.

String.prototype.lpad = function(padString, length) {
    var str = this;
    while (str.length < length)
        str = padString + str;
    return str;
}
for(var i = 0; i < 256; i++)
    window['b' + i.toString(2)] = window['b' + i.toString(2).lpad('0', 8)] = window['b' + i.toString(2).lpad('0', 4)] = i;
frodeborli
źródło
6

Może to się przyda:

var bin = 1111;
var dec = parseInt(bin, 2);
// 15
Siergiej Metłow
źródło
10
Śliczne, choć trochę dziwne. Ale to jest JavaScript dla Ciebie. binma przypisaną liczbę, która wygląda na binarną, ale w rzeczywistości jest analizowana jako podstawa 10. parseIntFunkcja oczekuje łańcucha jako pierwszego argumentu, więc zamienia go na "1111" (reprezentacja o podstawie 10), a następnie przetwarza go ponownie tak, jakby była to baza 2.
Ted Hopp
2

Nie, ale możesz użyć parseInt i opcjonalnie pominąć cudzysłowy.

parseInt(110, 2); // this is 6 
parseInt("110", 2); // this is also 6

Jedyną wadą pomijania cudzysłowów jest to, że w przypadku bardzo dużych liczb przepełnisz szybciej:

parseInt(10000000000000000000000, 2); // this gives 1
parseInt("10000000000000000000000", 2); // this gives 4194304
user1213898
źródło
1

Konwertuj ciągi binarne na liczby i odwrotnie.

var b = function(n) {
    if(typeof n === 'string')
        return parseInt(n, 2);
    else if (typeof n === 'number')
        return n.toString(2);
    throw "unknown input";
};
jpillora
źródło
-1

Wiem, że to właściwie nie odpowiada na zadane pytanie (na które udzielono już odpowiedzi kilka razy), ale sugeruję, abyś (lub inni zainteresowani tym tematem) wzięli pod uwagę fakt, że najbardziej czytelny i kompatybilny z poprzednimi / przyszłymi / różnymi przeglądarkami sposobem byłoby po prostu użycie reprezentacji szesnastkowej.

Z wyrażenia Q wydaje się, że mówisz tylko o używaniu literałów binarnych w swoim kodzie, a nie o przetwarzaniu binarnych reprezentacji wartości liczbowych (dla których parstInt jest właściwą drogą).

Wątpię, czy jest wielu programistów, którzy muszą obsługiwać liczby binarne, którzy nie są zaznajomieni z mapowaniem 0-F na 0000-1111. więc zasadniczo utwórz grupy po cztery i użyj notacji szesnastkowej.

więc zamiast pisać 101000000010 użyłbyś 0xA02, który ma dokładnie to samo znaczenie i jest znacznie bardziej czytelny i rzadziej zawiera błędy.


Weź pod uwagę czytelność. Spróbuj porównać, który z nich jest większy: 10001000000010010 lub 1001000000010010

a co jeśli napiszę je tak:
0x11012 lub 0x9012

epeleg
źródło
-3
// Conversion function
function bin(nb)
{
    return parseInt(nb.toString(2));
}

// Test
var stop = false;
while(!stop)
{
    var n = parseInt(prompt("Type a decimal number : "));
    alert(bin(n));

    var str = prompt("Retry ? Y / N");
    if(str === "N") { stop = true; }
}
Wyobraź sobie Breaker
źródło
parseInt (bez drugiego parametru) konwertuje ciąg binarny z powrotem na liczbę podstawową 10! np. 0b100 (4) staje się 100, a następnie przez alert zostaje zamieniony z powrotem w łańcuch!
Tom