2012-06-04 14 views
5

Also lese ich eine 12-Bit-Ganzzahl aus einem Byte-Array. Diese Zahl kann negativ sein, aber ich kann nicht herausfinden, wie man das in eine verwendbare Variable int16/int32 in C# umwandelt. Ich habe das Gefühl, dass ich etwas mit Bit-Shifting oder anderen bitweisen Operationen machen muss, aber ich bin bisher so weit gegangen. Kann mir jemand in die richtige Richtung zeigen?Konvertiere 12 Bit int in 16 oder 32 Bits

var x = 0xFFF;

Dies muss als -1 ausgedruckt werden, aber C# wird natürlich als int32 ausgegeben und als 4095 ausgegeben. Wenn dies in int16 oder int32 umgewandelt werden muss, behalte ich den negativen Wert bei.

Antwort

13

32-Bit: short ist ein signiertes bereits mit dem 12-Bit-Wert

x = (x >> 11) == 0 ? x : -1^0xFFF | x; 
+0

Funktioniert gut, vielen Dank! Verstand erklären, was hier vor sich geht? ich weiß was das >>^| tue aber nicht ganz nachvollziehbar. – Clarke76

+2

Grundsätzlich wird nach rechts geschoben, bis nur noch das Vorzeichenbit übrig ist. Wenn es Null ist, geben wir nur den ursprünglichen Wert zurück. Wenn es 1 ist, nehmen wir -1 (0xFFFFFFFF), schalten die unteren 12 Bits ('xor') aus und dann' or' mit dem ursprünglichen Wert, um die Bits darin einzuschalten. Das Ergebnis ist im Grunde nur die oberen 20 Bits des 32-Bit-Wertes einzuschalten. –

+0

yeah ... ich schrieb alles auf dem Papier und sah genau, was passierte. Das hat wirklich geholfen. Ich habe verstanden, dass das letzte Bit als Flag für Negativ verwendet wird. Danach war es einfach zu folgen. Danke noch einmal. – Clarke76

8

Sign-Erweiterung ohne Conditionalen x vorausgesetzt:

x = (x << 4) >> 4; 

Die Klammern sind rein für das Verständnis, was los ist. Bitverschiebungen sind linksassoziativ wie andere arithmetische und logische Operatoren. Der Grund, warum dies funktioniert, ist, dass >> eine arithmetische Rechtsverschiebung für vorzeichenbehaftete Typen ist. Das heißt, anstatt Nullen mit dem höchstwertigen Bit zu verschieben, dupliziert es das MSB so oft wie nötig.

Sign-Erweiterung im Allgemeinen von n Bit zu Bit m wäre dann:

x = (x << (m - n)) >> (m - n); 

Aus offensichtlichen Gründen m für sbyte, 16 für short, 32 für int und 64 für long-8 eingeschränkt würde. Auch hier sind die Klammern rein kosmetischer Natur. Subtraktion bindet dichter als Bit-Verschiebungen.

0

Erkennen Sie das Vorzeichenbit und erweitern Sie es. Für 16-Bit:

x = (x & 0x800 ? x^0xf000 : x); 
Verwandte Themen