将12位int转换为16位或32位

Cla*_*e76 6 c# bit-manipulation

所以我从字节数组中读取一个12位整数.这个数字可能是负数,但我无法弄清楚如何将其转换为c#中的可用变量int16/int32.有一种感觉我需要用位移或其他按位操作做一些事情,但到目前为止我一直在罢工.有人能指出我正确的方向.

var x = 0xFFF;

这需要打印为-1,但c#自然地转换为int32并打印为4095.如果需要转换为int16或int32,我如何保留负值.

And*_*per 13

32位:

x = (x >> 11) == 0 ? x : -1 ^ 0xFFF | x;
Run Code Online (Sandbox Code Playgroud)

  • 基本上向右移动直到仅留下符号位.如果它为零,那么我们只返回原始值.如果它为1则我们取-1(0xFFFFFFFF),关闭低12位(`xor`),然后用原始值关闭`或'以打开其中的位.结果基本上只是打开32位值的高20位. (2认同)

Wor*_*mbo 8

没有条件的符号扩展,假设x是已经包含12位值的带符号短路:

x = (x << 4) >> 4;
Run Code Online (Sandbox Code Playgroud)

括号纯粹是为了理解正在发生的事情.与其他算术和逻辑运算符一样,位移是左关联的.这有效的原因是>>签名类型的算术右移.这意味着,它不是在最重要的位上移入零,而是根据需要多次复制MSB.

一般从n一位到m另一位的符号扩展将是:

x = (x << (m - n)) >> (m - n);
Run Code Online (Sandbox Code Playgroud)

出于显而易见的原因,m将限制为8 for sbyte,16 for short,32 for int和64 long.同样,括号纯粹是装饰性的.减法比位移更紧密.