Czy w Javie mogę zdefiniować stałą całkowitą w formacie binarnym?

85

Podobnie jak w przypadku definiowania stałej liczby całkowitej w formacie szesnastkowym lub ósemkowym, czy mogę to zrobić w postaci binarnej?

Przyznaję, że to naprawdę łatwe (i głupie) pytanie. Moje wyszukiwania w Google są puste.

Aaron Fi
źródło
2
Po prostu do Twojej wiadomości, w prawie każdym języku programowania idiom polega na zapisywaniu stałych binarnych w szesnastkowym, a nie rzeczywistym łańcuchu binarnym.
abyx
3
Racja, ale wyobrażam sobie, że to dlatego, że hex jest najbliższą dostępną rzeczą, a nie dlatego, że coś jest nie tak z binarnym. W językach, których używałem, które obsługują literały binarne, nie sądzę, aby konwencja była taka, aby ignorować tę funkcję.
Ken
Rok 2017: akceptowana odpowiedź musi być podana przez Russa. Zobacz: stackoverflow.com/a/1692932/716079
Lourenco

Odpowiedzi:

65

Tak więc, wraz z wydaniem Java SE 7, notacja binarna jest standardem po wyjęciu z pudełka. Składnia jest dość prosta i oczywista, jeśli masz przyzwoite zrozumienie binarnego:

byte fourTimesThree = 0b1100;
byte data = 0b0000110011;
short number = 0b111111111111111; 
int overflow = 0b10101010101010101010101010101011;
long bow = 0b101010101010101010101010101010111L;

A konkretnie w kwestii deklarowania zmiennych poziomu klasy jako plików binarnych, nie ma absolutnie żadnego problemu z zainicjowaniem zmiennej statycznej za pomocą notacji binarnej:

public static final int thingy = 0b0101;

Uważaj tylko, aby nie przepełnić liczb zbyt dużą ilością danych, w przeciwnym razie pojawi się błąd kompilatora:

byte data = 0b1100110011; // Type mismatch: cannot convert from int to byte

Teraz, jeśli naprawdę chcesz zaszaleć, możesz połączyć tę inną fajną nową funkcję w Javie 7, znaną jako literały numeryczne z podkreśleniami. Spójrz na te fantazyjne przykłady notacji binarnej z dosłownymi podkreśleniami:

int overflow = 0b1010_1010_1010_1010_1010_1010_1010_1011;
long bow = 0b1__01010101__01010101__01010101__01010111L;

Czy to nie jest ładne i czyste, nie wspominając o bardzo czytelnym?

Wyciągnąłem te fragmenty kodu z małego artykułu, który napisałem na ten temat na TheServerSide. Zapraszam do sprawdzenia, aby uzyskać więcej informacji:

Java 7 i notacja binarna: opanowanie egzaminu OCP na programistę języka Java (OCPJP)

Cameron McKenzie
źródło
3
Dlaczego twoje dane bajtowe = 0b0000110011; ma 10 bitów? Jestem nowy w programowaniu, ale myślę, że powinno to wyglądać jak 0b00110011, aby zmieścić 8 bitów typu danych bajtowych.
Mike
1
Dla każdego, kto zastanawia się tak samo jak Mike, dzieje się tak dlatego, że kompilator konwertuje ją na liczbę, którą reprezentuje - możesz mieć dziesiątki wiodących zer i nie wpłyną one na rzeczywistą wartość. Proces kompilacji jest zasadniczo taki sam, jak gdybyś wpisał tam ułamek dziesiętny.
Luke Briggs
1
z definicji bajt typu pierwotnego może przechowywać 256 liczb od -128 do 127 (od -128 do -1 i od 0 do 127). Ale jak przedstawić -128 używając literału binarnego. np. bajt b = -0b1111111; oznacza -127, ale co z -128?
nirmalsingh
152

W Javie 7:

int i = 0b10101010;

W starszych wersjach języka Java nie ma literałów binarnych (alternatywne rozwiązania można znaleźć w innych odpowiedziach).

Russ Hayward
źródło
33
Chciałbym również zaznaczyć, że mogą istnieć _znaki, aby sekwencja była bardziej czytelna: int i = 0b1010_1010_0011;
user12345613
@Russ Co oznacza tutaj 0b? Jak nazywa się ta funkcja w Javie 7?
Geek
1
0b oznacza binarny. Ta funkcja nosi nazwę literałów binarnych: docs.oracle.com/javase/7/docs/technotes/guides/language/ ...
Russ Hayward
1
Uwielbiam tę nową reprezentację danych binarnych. Reprezentacja typu String byłaby bardzo trudna do odczytania. Spójrz na różnicę w zaakceptowanej odpowiedzi i tej od „@ user12345613”. +1 dla niego.
Marcello de Sales,
54

W Javie nie ma literałów binarnych, ale przypuszczam, że możesz to zrobić (chociaż nie widzę sensu):

int a = Integer.parseInt("10101010", 2);
Ed S.
źródło
1
Między innymi, wzór kropkowania dla rasteryzacji linii i wielokątów jest określany jako liczba całkowita w kilku popularnych bibliotekach graficznych. Użycie parseInt lub parseShort umożliwia programiście łatwą wizualizację wzorca.
charstar
5
Od wersji Java 7 odpowiedź Russa Haywarda jest poprawna. Przed wersją Java 7 można skorzystać z narzędzia online lub ulubionego kalkulatora, aby przekonwertować dane binarne na jedną z notacji rozpoznawanych w starszych wersjach języka Java (ósemkowa, dziesiętna lub szesnastkowa). Jeśli używana jest inna podstawa, komentarz opisowy zawierający reprezentację binarną można umieścić w deklaracji, aby wyjaśnić wartość dla czytelników.
Jason C
To raczej brudne rozwiązanie, prawda? Po prostu bierzesz 16 bajtów, aby reprezentować 1 bajt (nie licząc drugiego argumentu i konwersji). Oczywiście, chyba że kompilator to zoptymalizuje, w co wątpię.
Tomáš Zato - Przywróć Monikę
@ TomášZato: Tak, ale jakie rozwiązanie byś zaproponował, biorąc pod uwagę, że język nie obsługuje literałów binarnych, kiedy pisałem tę odpowiedź? Russ Hayward powinien teraz otrzymać akceptowaną odpowiedź.
Ed S.,
Proponuję zrezygnować z komfortu i użyć liczb całkowitych. W samej definicji zmiennej jest ok, ale ta odpowiedź może zmotywować użytkowników do zastosowania tego podejścia w przypadku pętli itp. I ogólnie uważam, że programista powinien spróbować zrezygnować z własnego komfortu dla jakiejś wydajności.
Tomáš Zato - Przywróć Monikę
18

Odpowiedź od Eda Swangrena

public final static long mask12 = 
  Long.parseLong("00000000000000000000100000000000", 2);

działa w porządku. Użyłem longzamiast nich inti dodałem modyfikatory, aby wyjaśnić możliwe użycie jako maski bitowej. Takie podejście wiąże się jednak z dwiema niedogodnościami.

  1. Bezpośrednie wpisanie wszystkich tych zer jest podatne na błędy
  2. Wynik nie jest dostępny w formacie dziesiętnym ani szesnastkowym w czasie opracowywania

Mogę zaproponować alternatywne podejście

public final static long mask12 = 1L << 12;

To wyrażenie pokazuje, że dwunasty bit to 1 (licznik zaczyna się od 0, od prawej do lewej); a po najechaniu kursorem myszy na etykietkę

long YourClassName.mask12 = 4096 [0x1000]

pojawia się w Eclipse. Możesz zdefiniować bardziej skomplikowane stałe, takie jak:

public final static long maskForSomething = mask12 | mask3 | mask0;

lub wyraźnie

public final static long maskForSomething = (1L<<12)|(1L<<3)|(1L<<0);

Wartość zmiennej maskForSomethingbędzie nadal dostępna w Eclipse w czasie projektowania.

chgman
źródło
Genialne rozwiązanie! (publiczna końcowa statyczna długa maska12 = 1L << 12;)
Jyro117
16

Używanie stałych binarnych do maskowania

Zadeklaruj stałe:

public static final int FLAG_A = 1 << 0;
public static final int FLAG_B = 1 << 1;
public static final int FLAG_C = 1 << 2;
public static final int FLAG_D = 1 << 3;

i używaj ich

if( (value & ( FLAG_B | FLAG_D )) != 0){
    // value has set FLAG_B and FLAG_D
}
pawelzieba
źródło
12

Wyszukaj w Google „Składnia literałów Java”, a otrzymasz kilka wpisów.

Istnieje składnia ósemkowa (prefiks liczby 0), składnia dziesiętna i składnia szesnastkowa z przedrostkiem „0x”. Ale nie ma składni dla notacji binarnej.

Kilka przykładów:

int i = 0xcafe ; // hexadecimal case
int j = 045 ;    // octal case
int l = 42 ;     // decimal case
Pierre
źródło
1
To nie odpowiada na pytanie.
Michael McQuade
Rok 2017: Na szczęście istnieje zapis binarny. Zaczyna się od „0b”. Przykład: byte b = 0b01000001(dla lepszej czytelności byte b = 0b0100_0001).
Lourenco
2

Jeśli chcesz bawić się dużą ilością plików binarnych, możesz zdefiniować kilka stałych:

public static final int BIT_0 = 0x00000001;
public static final int BIT_1 = 0x00000002;

itp.

lub

public static final int B_00000001 = 0x00000001;
public static final int B_00000010 = 0x00000002;
public static final int B_00000100 = 0x00000004;
Anthony Hayward
źródło
0

Nieco bardziej niezręczna odpowiedź:

public class Main {

    public static void main(String[] args) {
        byte b = Byte.parseByte("10", 2);
        Byte bb = new Byte(b);
        System.out.println("bb should be 2, value is \"" + bb.intValue() + "\"" );
    }

}

która wyprowadza [java] bb powinna wynosić 2, wartość to „2”

NSherwin
źródło