ich bekomme Daten die im Zweikomplement vorliegen.
Wie wandle ich sie korrekt „zurück“?
Die Umwandlung einer Zahl in das zweite Komplement soll so passieren:
Converting a negative decimal number (ie: -3) into binary takes 3 steps:
1) convert the positive version of the decimal number into binary (ie: 3 = 0011)
2) flips the bits (ie: 0011 becomes 1100)
3) add 1 (ie: 1100 + 0001 = 1101)
Versuche mich hier seid Stunden den Prozess „umzukehren“…
Somit solltest du auch mit unpack zu einem sinnvollen Ergebnis kommen.
Allerdings zeigt dein Beispiel nur ein Nibble und kein Byte.
Eigentlich wäre ja -3 => 11111101bei einem Byte. Und das Beispiel zeigt nur die unteren 4 Bits => 1101
Als Byte liefert unpack mit
var_dump(unpack(„c“,$Byte));
auch das korrekte Ergebnis.
Michael
Unter der Annahme, das es sich um eine 8Bit Komplement handelt läuft das im einzelnen so ab
<?php
$v=-3; //Ausgangswert
$v1=abs($v); //positive Zahl
$v2=(~$v1) &255; //Bits negieren und auf 8Bit beschränken
$v3=$v2+1; eins addieren
printf("%d,%d,%08b,%08b,%08b,%d
",$v,$v1,$v1,$v2,$v3,$v3);
?>
ergibt
-3,3,00000011,11111100,11111101,253
oder einfach wenn immer $v negativ ist
print ($v1+256); //256=255+1
Wenn es sich um ein 16Bit komplement handelt, dann einfach die Basis auf 65536 ändern.
Sie sind aufgeteilt in drei Bytes. Ist die Zahl im positiven Bereich ist das nicht mein Problem, aber sehr wohl wenn sie in den negativen Bereich geht.
Um die Daten und das Vorzeichen zu „isolieren“ habe ich so gemacht:
…schaue ich mir die Beispiele für negative Werte an, dann würde ich $Value zunächst
$Value = ~$Value; // negieren
$Value = $Value + 1;
$Value = $Value * Multiplikator;
Funktioniert aber aus irgendeinem Grund nicht? Vielleicht weil das nicht mit der „Summe“ der Bytes gemacht werden muss, sondern zunächst mit den einzelnen Bytes?
Es müßte aber etwas in der Höhe von ca. -1592 herauskommen…
Joachim
Nachtrag: Irgendwie macht dieses ~$Value nicht das was ich erwarte:
2503 wäre bitweise gesehen genau das Gegenstück von 1592, stattdessen wird aus 2503 „nur“ -2504…