Преобразование 12 бит int в 16 или 32 бит

поэтому я читаю 12-битное целое число из массива байтов. Это число может быть отрицательным, но я не могу понять, как преобразовать его в полезную переменную int16/int32 в c#. Есть чувство, что мне нужно будет сделать что-то с Бит-сдвигом или другими побитовыми операциями, но я до сих пор вычеркивал. Может кто-нибудь указать мне в правильном направлении.

var x = 0xFFF;

Это должно печататься как -1, но c#, естественно, приводит к int32 и печатает как 4095. Если это нужно бросить для int16 или int32 как сохранить отрицательное значение.

3 ответов


32-битные:

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

подписать расширение без условных обозначений, предполагая x является подписанным коротким, уже содержащим 12-битное значение:

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

скобки предназначены исключительно для понимания того, что происходит. Битовые сдвиги влево-ассоциативно, как и другие арифметические и логические операторы. Причина, по которой это работает, заключается в том, что >> - это арифметический сдвиг вправо для знаковых типов. Это означает, что вместо смещения нулей в самом значимом бит, он дублирует MSB столько раз, сколько необходимый.

расширение знака вообще от n бита m бита будет выглядеть так:

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

по понятным причинам m будет ограничено до 8 для sbyte, 16 в short, 32 в int и 64 для long. Опять же, скобки чисто косметические. Вычитание связывает сильнее, чем битовые сдвиги.


обнаружьте знак-бит и расширьте его. Для 16-разрядных:

x = ( x & 0x800 ? x | 0xf000 : x );