2009-11-14 20 views
29

Wie spalte ich eine ganze Zahl in 2-Byte-Binärdatei?

Gegeben
private int width = 400; 
private byte [] data = new byte [2]; 

I die ganze Zahl "Breite" in zwei Bytes und Lastdaten [0] mit dem High-Byte und Daten geteilt werden soll [1] mit dem niedrigen Byte.

dass binärer Wert von 400 = 1 1001 0000 so data [0] 0000 0001 und Daten [1] sollten 1001 0000

Antwort

64

Mit einfachen bitweisen Operationen enthalten, enthält:

data[0] = (byte) (width & 0xFF); 
data[1] = (byte) ((width >> 8) & 0xFF); 

Wie es funktioniert:

  • & 0xFF maskiert alle, aber die niedrigsten acht Bits.
  • >> 8 verwirft die niedrigsten 8 Bits, indem alle Bits 8 Stellen nach rechts verschoben werden.
  • Die Besetzung an Byte ist notwendig, da diese bitweise Operationen auf einer int arbeiten und ein int zurückkehren, die ein größerer Datentyp als byte ist. Der Fall ist sicher, da alle Nicht-Null-Bits in die byte passen. Weitere Informationen finden Sie unter Conversions and Promotions.

Edit:Taylor L richtig bemerkt, dass, obwohl >> Arbeiten in diesem Fall kann es zu falschen Ergebnissen führen, wenn Sie diesen Code verallgemeinern zu vier Bytes (da in Java ein int 32 Bit). In diesem Fall ist es besser >>> anstelle von >> zu verwenden. Weitere Informationen finden Sie unter Java tutorial on Bitwise and Bit Shift Operators.

+4

>> möglicherweise nicht was Sie wollen. >>> trägt nicht das Vorzeichen-Bit, wenn Sie verschieben, so dass es wahrscheinlich besser ist, in diesem Fall zu verwenden, wenn Sie alle 4 Bytes erfassen möchten. –

+0

@ Taylor: gute Bemerkung! – Stephan202

+0

wenn ich "new byte [] {width & 0xFF, (width >> 8) & 0xFF}" der compiler sagt "möglich verlust der präzision erforderlich byte gefunden int" –

1

Integer ist 32 Bit (= 4 Bytes) in Java, weißt du?

Breite & 0xff wird Ihnen das erste Byte, Breite & 0xff00 >> 8 gibt Ihnen die zweite usw.

-1

Um das High-Byte zu erhalten, nach rechts verschieben um 8 Bits dann die oberen Bytes maskieren . In ähnlicher Weise maskieren Sie die oberen Bytes ab, um das niederwertige Byte zu erhalten.

data[0] = (width >> 8) & 0xff; 
data[1] = width & 0xff; 
+0

Sie müssen als Bytes umwandeln. –

+0

Entschuldigung - versuchte, das Prinzip zu veranschaulichen, aber Sie haben Recht! –

0
int width = 400; 
byte [] data = new byte [2]; 

data[0] = (byte) ((width & 0xFF00) >> 8); 
data[1] = (byte) (width & 0xFF); 

for(int b = 0; b < 2; b++) { 
    System.out.println("printing byte " + b); 
    for(int i = 7; i >= 0; i--) { 
     System.out.println(data[b] & 1); 
     data[b] = (byte) (data[b] >> 1); 
    } 
} 
4

Dies sollte das tun, was Sie für ein 4-Byte-int wollen. Beachten Sie, dass es das Low-Byte bei Offset 0 speichert. Ich werde es dem Leser als Übung überlassen, sie nach Bedarf zu ordnen.

public static byte[] intToBytes(int x) { 
    byte[] bytes = new byte[4]; 

    for (int i = 0; x != 0; i++, x >>>= 8) { 
     bytes[i] = (byte) (x & 0xFF); 
    } 

    return bytes; 
} 
11

Für zwei Bytes, die die sauberste Lösung Umwandlung ist

data[0] = (byte) width; 
data[1] = (byte) (width >>> 8); 

für eine ganze Zahl bis vier Bytes der Code-Umwandlungs-

data[0] = (byte) width; 
data[1] = (byte) (width >>> 8); 
data[2] = (byte) (width >>> 16); 
data[3] = (byte) (width >>> 24); 

wäre Es spielt keine Rolle, ob >> oder> >> wird zum Verschieben verwendet, irgendwelche Bits, die durch die Zeichenerweiterung erzeugt werden, werden nicht in den resultierenden Bytes enden.

Siehe auch this answer.

0

Ich schlage vor, Sie sehen sich die Quelle für HeapByteBuffer. Es hat den Konvertierungscode für alle primitiven Datentypen. (In der Tat könnten Sie einfach einen ByteBuffer verwenden;)

Verwandte Themen