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 long
vor 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.
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. –
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
Ihre Bytes sind 16 Bits ?? Bitte prüfe. Es gibt keine Möglichkeit, den Wert 5172 in einer Variablen vom Typ Byte zu speichern. –