Kann ich in Java eine Ganzzahlkonstante im Binärformat definieren?

85

Ähnlich wie Sie eine Ganzzahlkonstante hexadezimal oder oktal definieren können, kann ich dies auch binär tun?

Ich gebe zu, das ist eine wirklich einfache (und dumme) Frage. Meine Google-Suchanfragen sind leer.

Aaron Fi
quelle
2
Nur zu Ihrer Information, in so ziemlich jeder Programmiersprache besteht die Redewendung darin, binäre Konstanten in hexadezimaler Form zu schreiben und nicht die eigentliche binäre Zeichenfolge.
Abyx
3
Richtig, aber ich stelle mir vor, das liegt daran, dass Hex am nächsten verfügbar ist, nicht daran, dass mit Binär etwas nicht stimmt. In Sprachen, die ich verwendet habe und die binäre Literale unterstützen, besteht die Konvention meiner Meinung nach nicht darin, diese Funktion zu ignorieren.
Ken
Jahr 2017: Die akzeptierte Antwort muss die von Russ sein. Siehe: stackoverflow.com/a/1692932/716079
Lourenco

Antworten:

65

Mit der Veröffentlichung von Java SE 7 ist die binäre Notation standardmäßig verfügbar. Die Syntax ist recht einfach und offensichtlich, wenn Sie ein gutes Verständnis von Binär haben:

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

Und speziell im Hinblick auf die Deklaration von Variablen auf Klassenebene als Binärdateien ist es absolut kein Problem, eine statische Variable mit Binärnotation zu initialisieren:

public static final int thingy = 0b0101;

Achten Sie nur darauf, die Zahlen nicht mit zu vielen Daten zu überlaufen, da sonst ein Compilerfehler angezeigt wird:

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

Wenn Sie wirklich Lust haben, können Sie diese andere nette neue Funktion in Java 7, die als numerische Literale bekannt ist, mit Unterstrichen kombinieren. Schauen Sie sich diese ausgefallenen Beispiele für binäre Notation mit wörtlichen Unterstrichen an:

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

Ist das nicht schön und sauber, ganz zu schweigen von der guten Lesbarkeit?

Ich habe diese Codefragmente aus einem kleinen Artikel gezogen, den ich über das Thema bei TheServerSide geschrieben habe. Fühlen Sie sich frei, es für weitere Details zu überprüfen:

Java 7 und Binärnotation: Beherrschen der OCP Java Programmer (OCPJP) -Prüfung

Cameron McKenzie
quelle
3
Warum sind Ihre Byte-Daten = 0b0000110011; hat 10 Bits? Ich bin neu in der Programmierung, aber ich denke, es sollte 0b00110011 aussehen, um 8 Bit Byte-Datentyp zu passen.
Mike
1
Für alle, die sich das Gleiche wie Mike fragen, liegt es daran, dass der Compiler es in die Zahl konvertiert, die es darstellt - Sie könnten zehn führende Nullen haben, die den tatsächlichen Wert nicht beeinflussen. Der Kompilierungsprozess ist im Wesentlichen der gleiche, als hätten Sie dort eine Dezimalstelle geschrieben.
Luke Briggs
1
Per Definition kann das primitive Typbyte 256 Zahlen zwischen -128 und 127 (-128 bis -1 und 0 bis 127) speichern. Aber wie man -128 mit einem binären Literal darstellt. für zB Byte b = -0b1111111; bedeutet -127, aber was ist mit -128?
Nirmalsingh
152

In Java 7:

int i = 0b10101010;

In älteren Java-Versionen gibt es keine binären Literale (Alternativen finden Sie in den anderen Antworten).

Russ Hayward
quelle
33
Ich möchte auch darauf hinweisen, dass es _Zeichen geben kann , um die Sequenz besser lesbar zu machen: int i = 0b1010_1010_0011;
user12345613
@Russ Was bedeutet 0b hier? Wie heißt diese Funktion in Java 7?
Geek
1
0b bedeutet binär. Die Funktion heißt binäre Literale: docs.oracle.com/javase/7/docs/technotes/guides/language/…
Russ Hayward
1
Ich liebe diese neue Darstellung von Binärdaten. Die String-Darstellung wäre sehr schwer zu lesen. Sehen Sie sich den Unterschied zwischen der akzeptierten und der Antwort von "@ user12345613" an. +1 für ihn.
Marcello de Sales
54

Es gibt keine binären Literale in Java, aber ich nehme an, dass Sie dies tun könnten (obwohl ich den Punkt nicht verstehe):

int a = Integer.parseInt("10101010", 2);
Ed S.
quelle
1
Unter anderem wird das Punktierungsmuster für die Linien- und Polygonrasterung in mehreren gängigen Grafikbibliotheken als Ganzzahl angegeben. Mit parseInt oder parseShort kann der Entwickler das Muster einfach visualisieren.
Charstar
5
Seit Java 7 ist Russ Haywards Antwort die richtige Antwort. Vor Java 7 können Sie ein Online-Tool oder Ihren bevorzugten Taschenrechner verwenden, um Binärdateien in eine der Notationen zu konvertieren, die von alten Java-Versionen (oktal, dezimal oder hexadezimal) erkannt wurden. Wenn ein anderer Radix verwendet wird, kann bei der Deklaration ein beschreibender Kommentar mit der binären Darstellung eingefügt werden, um den Wert für die Leser zu verdeutlichen.
Jason C
Das ist eine ziemlich schmutzige Lösung, nicht wahr? Sie benötigen nur 16 Bytes, um 1 Byte darzustellen (ohne das zweite Argument und die Konvertierung). Natürlich, es sei denn, der Compiler optimiert dies, was ich bezweifle.
Tomáš Zato - Wiedereinsetzung Monica
@ TomášZato: Ja, aber welche Lösung würden Sie vorschlagen, da die Sprache keine binären Literale unterstützt, als ich diese Antwort schrieb? Russ Hayward sollte jetzt die akzeptierte Antwort haben.
Ed S.
Ich würde vorschlagen, auf den Komfort zu verzichten und ganze Zahlen zu verwenden. In der Variablendefinition selbst ist dies in Ordnung, aber diese Antwort könnte Benutzer dazu motivieren, diesen Ansatz für Schleifen usw. zu verwenden. Und im Allgemeinen denke ich, dass Programmierer versuchen sollten, seinen eigenen Komfort für eine gewisse Leistung aufzugeben.
Tomáš Zato - Wiedereinsetzung Monica
18

Die Antwort von Ed Swangren

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

funktioniert gut. Ich habe longstattdessen intdie Modifikatoren verwendet und hinzugefügt, um die mögliche Verwendung als Bitmaske zu verdeutlichen. Es gibt jedoch zwei Unannehmlichkeiten bei diesem Ansatz.

  1. Die direkte Eingabe all dieser Nullen ist fehleranfällig
  2. Das Ergebnis ist zum Zeitpunkt der Entwicklung nicht im Dezimal- oder Hex-Format verfügbar

Ich kann einen alternativen Ansatz vorschlagen

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

Dieser Ausdruck macht deutlich, dass das 12. Bit 1 ist (die Zählung beginnt bei 0, von rechts nach links); und wenn Sie den Mauszeiger bewegen, wird der Tooltip angezeigt

long YourClassName.mask12 = 4096 [0x1000]

erscheint in Eclipse. Sie können kompliziertere Konstanten definieren wie:

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

oder explizit

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

Der Wert der Variablen maskForSomethingist zur Entwicklungszeit weiterhin in Eclipse verfügbar.

chgman
quelle
Geniale Lösung! (öffentliche endgültige statische lange Maske12 = 1L << 12;)
Jyro117
16

Verwenden von Binärkonstanten zum Maskieren

Konstanten deklarieren:

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;

und benutze sie

if( (value & ( FLAG_B | FLAG_D )) != 0){
    // value has set FLAG_B and FLAG_D
}
pawelzieba
quelle
12

Suchen Sie bei Google nach "Java-Literal-Syntax" und Sie kommen auf einige Einträge.

Es gibt eine Oktalsyntax (Präfix Ihrer Zahl mit 0), eine Dezimalsyntax und eine Hexadezimalsyntax mit einem Präfix "0x". Aber keine Syntax für die binäre Notation.

Einige Beispiele:

int i = 0xcafe ; // hexadecimal case
int j = 045 ;    // octal case
int l = 42 ;     // decimal case
Pierre
quelle
1
Dies beantwortet die Frage nicht.
Michael McQuade
Jahr 2017: Glücklicherweise gibt es eine Notation für die binäre Darstellung. Es beginnt mit "0b". Beispiel: byte b = 0b01000001(zur besseren Lesbarkeit byte b = 0b0100_0001).
Lourenco
2

Wenn Sie mit viel Binärdatei herumspielen möchten, können Sie einige Konstanten definieren:

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

etc.

oder

public static final int B_00000001 = 0x00000001;
public static final int B_00000010 = 0x00000002;
public static final int B_00000100 = 0x00000004;
Anthony Hayward
quelle
0

Etwas umständlichere Antwort:

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() + "\"" );
    }

}

welche Ausgabe [java] bb sollte 2 sein, Wert ist "2"

NSherwin
quelle