Bitweises UND, bitweise Inclusive OR Frage, in Java
-
05-09-2019 - |
Frage
Ich habe ein paar Zeilen Code in einem Projekt, dass ich nicht den Wert sehen ...
buffer[i] = (currentByte & 0x7F) | (currentByte & 0x80);
Es liest die FILEBUFFER aus einer Datei, als Bytes gespeichert, und dann überträgt dann puffern [i] wie gezeigt, aber ich kann nicht verstehen, was der Hauptzweck ist, irgendwelche Ideen?
Danke
Lösung
Wie die anderen Antworten bereits erwähnt, (currentByte & 0x7F) | (currentByte & 0x80)
entspricht (currentByte & 0xFF)
. Die JLS3 15.22.1 sagt dies wird gefördert zu einem int
:
Wenn beide Operanden eines Operators &, ^ Oder | eine Art ist, von dem ist Cabriolet (§5.1.8) auf eine primitive Integral-Typ, binäre Zahlen Förderung wird zunächst auf die durchgeführt Operanden (§5.6.2). Die Art der bitweise Operator Ausdruck ist die gefördert Typ der Operanden.
da JLS3 5.6.2 sagt dass, wenn currentByte
Typ byte
hat und 0x7F
ist ein int
(und dies ist der Fall ist), dann werden beide Operanden gefördert int
.
Daher buffer
wird ein Array von Elementtyp int
oder breiter sein.
Nun, durch & 0xFF
auf einem int
Durchführung effektiv wir den ursprünglichen byte
Bereichs -128..127 in den unsigned Bereich 0..255 Karte, oft eine Operation durch java.io
verwendet Ströme zum Beispiel.
Sie können dies im folgenden Code-Schnipsel in Aktion sehen. Beachten Sie, dass zu verstehen, was hier geschieht, müssen Sie wissen, dass Java speichert ganzzahlige Typen, mit Ausnahme char
, wie 2-Komplement Werte.
byte b = -123;
int r = b;
System.out.println(r + "= " + Integer.toBinaryString(r));
int r2 = b & 0xFF;
System.out.println(r2 + "= " + Integer.toBinaryString(r2));
Schließlich für ein reales Beispiel, überprüfen Sie die Javadoc und Umsetzung der read
Methode von java.io.ByteArrayInputStream
aus:
/**
* Reads the next byte of data from this input stream. The value
* byte is returned as an <code>int</code> in the range
* <code>0</code> to <code>255</code>. If no byte is available
* because the end of the stream has been reached, the value
* <code>-1</code> is returned.
*/
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
Andere Tipps
(currentByte & 0x7F) | (currentByte & 0x80)
entspricht
currentByte & (0x7F | 0x80)
, die gleich
currentByte & 0xFF
, die als
genau das gleiche ist currentByte
Edit: Ich sah nur auf der rechten Seite der Zuweisung, und ich denke immer noch die Gleichwertigkeit wahr ist
.Allerdings scheint es, wie der Code will das signierte Byte zu einem größeren Typ, während der Interpretation der Byte als unsigned werfen.
Gibt es einen einfacheren Weg, unterzeichnet-Byte ohne Vorzeichen in Java zu werfen?
Ich glaube, jemand hat zu viel denken hier. Das ist einfach nicht richtig.
Ich habe nur eine Bemerkung
- Der ursprüngliche Autor war besorgt über die Laufzeit des Bytes mit einer nativen Signed Integer ersetzt (vermutlich 32-bit) und explizit versucht, uns zu sagen, etwas über das Vorzeichenbit „special“? sein
Es ist Code hinter sich gelassen. Es sei denn, Sie wissen, dass Sie auf einer fischigen Laufzeit sind? Was ist der Typ des ‚Puffer‘ eigentlich?
Die komplizierte bitweise Logik ist völlig überflüssig.
for (int i = 0; i < buffer.length; i++) {
buffer[i] = filebuffer[currentPosition + i] & 0xff;
}
macht das Gleiche. Wenn Puffer als Array von Bytes deklariert wird, können Sie sogar verlassen, um die & 0xff, aber leider ist die Erklärung nicht gezeigt.
Der Grund dafür kann sein, dass der ursprüngliche Entwickler von Bytes verwechselt wurde in Java unterzeichnet werden.
Das Ergebnis einer bitweisen UND-Operation weist eine 1 an, daß die Bits, wo beide Bits 1 sind, während das Ergebnis einer bitweisen ODER-Operation auf ein hase, dass die Bits in dem entweder eines der Bits 1 ist Bot.
So ein Beispiel Auswertung für den Wert 0x65:
01100101 0x65
& 01111111 0x7F
===============
01100101 0x65
01100101 0x65
& 10000000 0x80
===============
00000000 0x00
01100101 0x65
| 00000000 0x00
===============
01100101 0x65
Die gute Sache über diese Art von logischen Operationen. Sie jede mögliche Kombination ausprobieren können (alle 256 von ihnen) und stellen Sie sicher, dass Sie die Antwort bekommen Sie erwartet
Es stellt sich heraus, um die Datei, die das Byte aus war in einer signierten Bit Notation gelesen wurde, und eine andere Länge, deshalb wurde es requried diese Aufgabe zu erfüllen, damit es in dem Java-int-Typ erweitert werden, unter Beibehaltung seine korrekte Zeichen:)