2017-02-15 4 views
-1

ich so etwas wie diese:konvertieren 64-Bit-Daten zu signed long Wert

byte[0] = 0001 0100 0011 0100 (dec value: 5172) 
byte[1] = 0000 0000 0111 1100 (dec value: 124) 
byte[2] = 0000 0000 0000 0000 (dec value: 0) 
byte[3] = 0000 0000 0000 0000 (dec value: 0) 

ich sie kombinieren möchte und einen langen Wert in Java machen. Wie geht das?

Kann es auf diese Weise konvertiert werden?

result = 0 + (0 x 2^16) + (0 x 2^16) + (124 x 2^32) + (5127 x 2^48)

dh.

result = byte [3] + (byte [2] x 2^16) + (byte [1] x 2^32) + (Byte [0] x 2^48)

Edit: Lassen Ich versuche es besser zu erklären. Wenn ich das Tool ModScan32 öffne und eine Verbindung zu meinem Gerät herstelle, sehe ich einige Register. In diesem Tool gibt es verschiedene Arten von Optionen zum Anzeigen von Daten. Einer von ihnen soll sie als binär oder dezimal darstellen. Wenn ich binär oder dezimal wähle, bekomme ich Werte, wie sie in meinem obigen Beispiel sind. Wenn ich diese Daten mit meiner Software lese, bekomme ich genau die gleichen (konvertierten Werte) in der Dezimalzahl. Nun ist meine Frage, ob es notwendig ist, Daten in 4 16-Bit-Registern zu halten, und ich kenne ihre Dezimalwerte, was ist der richtige Weg, diese Werte aus Registern zu kombinieren und einen echten Wert zu erhalten?

+0

Ich bekomme nicht wirklich, wie Ihre Werte gespeichert werden, aber wenn Sie Dezimalwerte kennen, warum nicht einfach schreiben Sie sie? Andernfalls werden die eingebauten Long.parseLong-Methoden berücksichtigt. –

+0

Die Werte, wenn ich sie vom Gerät lese, erhalte Dezimalwerte, wie im obigen Beispiel, jeder Wert im Gerät wird in 4 16-Bit-Registern gespeichert, daher muss ich diese Werte von Registern in Long konvertieren Wert. Ich bin mir nicht sicher, wie ich das machen soll. – Josef

+2

Ihre Bytes sind 16 Bits ?? Bitte prüfe. Es gibt keine Möglichkeit, den Wert 5172 in einer Variablen vom Typ Byte zu speichern. –

Antwort

1

Ihre Idee ist grundsätzlich in Ordnung. Es gibt ein paar Dinge zu beachten.

Ich glaube, das Ergebnis, das Sie in Ihrem Fall sind, ist 0001010000110100000000000111110000000000000000000000000000000000.

Hier ist ein Versuch, das nicht funktioniert:

int[] registers = { 5172, 124, 0, 0 }; 
    long result = registers[0] << 48 | registers[1] << 32 | registers[2] << 16 | registers[3]; 
    System.out.println(Long.toBinaryString(result)); 

<< 48 Mittel 48 Bits nach links verschoben, die gut genug sein sollte, nicht wahr? | ist ein bitweises logisches oder, es füllt die 1 Bits von jedem Operanden in die gleiche Bitposi- tion des Ergebnisses. Sie könnten stattdessen + verwenden, wenn Sie es vorziehen.

Diese Drucke:

10100001101000000000001111100 

Wir haben leider nur die ersten 32 Bits des Ergebnisses haben, das ist nicht gut genug. Wenn Sie versuchen, es zu lesen, beachten Sie, dass Long.toBinaryString() führende Nullen nicht enthält. Stellen Sie sich einfach 3 Nullen vor der Nummer vor.

Aber was ging? Wohin sind die letzten 32 Bits gegangen? Selbst wenn sie nur Nullen waren. Das Problem ist, dass wir die Berechnung in int s machen, sie sind 32 Bits, nicht 64. EDIT: Meine vorherige Erklärung war in diesem Punkt nicht völlig richtig. Die Wahrheit ist: Wenn << auf einem int getan wird, werden nur die letzten 5 Bits des rechten Operanden berücksichtigt, und da 48 110000 binär ist, wird nur 10000 verwendet, so dass die Verschiebung dieselbe ist wie << 16. Ähnlich ist << 32 das gleiche wie << 0, keine Verschiebung überhaupt. Also registers[0] und [1] sind in der falschen Bitposition gelandet. Die Lösung ist einfach, wenn Sie es wissen: Wir müssen zu longvor konvertieren, die Berechnung zu tun.Nun sind die letzten Bits des rechten Operanden verwendet werden, so 48 und 32 sind zu verstehen als 48 und 32:

long result = ((long) registers[0]) << 48 | ((long) registers[1]) << 32 | registers[2] << 16 | registers[3]; 

Dieses Mal haben wir

1010000110100000000000111110000000000000000000000000000000000 

wieder bekommen, stellen drei Null-Bits in vorne und alles ist wie erwartet.

Es gibt noch eine Sache. Sagen bekam man einen negativen Wert aus einem Register, zum Beispiel:

int[] registers = { 5172, -124, 0, 0 }; 

Die Berechnung, die gerade jetzt uns

64 Bits gedruckt gearbeitet gibt Dieses Mal gibt es, so ist es leicht zu sehen, Am Anfang gibt es zu viele 1s. Sie kommen aus der int Darstellung von -124. Die Lösung besteht darin, sie zu maskieren:

int[] registers = { 5172, -124, 0, 0 }; 
    long result = ((long) registers[0] & 0xFFFF) << 48 
      | ((long) registers[1] & 0xFFFF) << 32 
      | (registers[2] & 0xFFFF) << 16 
      | (registers[3] & 0xFFFF); 
    System.out.println(Long.toBinaryString(result)); 

0xFFFF 16 1-Bits ist, und & ist die bitweise logische ‚und‘, einen 1-Bit in dem Ergebnis gibt nur in Positionen, bei denen beiden Operanden haben einen 1 Bit. Nun wird -124 maskiert 1111111110000100 so das Ergebnis ist die erwartete:

1010000110100111111111000010000000000000000000000000000000000 

Das sollte es tun.

+0

Vielen Dank für Ihre ausführliche Erklärung. Es hat wirklich zu einem besseren Verständnis beigetragen. – Josef

+0

Freut mich, dass es dir gefallen hat. Wenn Sie die genaue Wahrheit wollen, beachten Sie bitte meine Korrektur, wie '<< 48' funktioniert. –

Verwandte Themen