我正在从字节数组中读取一个12位的整数。这个数字可以是负数,但我不知道如何将其转换为可用的int16/int32类型变量。我有一种感觉需要使用位移或其他按位操作,但到目前为止我一直失败了。请问有人能指点我正确的方向吗?
var x = 0xFFF;
这应该输出为-1,但是C#自然地将其强制转换为int32并输出为4095。如果需要将其强制转换为int16或int32,该如何保留负数值呢?
我正在从字节数组中读取一个12位的整数。这个数字可以是负数,但我不知道如何将其转换为可用的int16/int32类型变量。我有一种感觉需要使用位移或其他按位操作,但到目前为止我一直失败了。请问有人能指点我正确的方向吗?
var x = 0xFFF;
这应该输出为-1,但是C#自然地将其强制转换为int32并输出为4095。如果需要将其强制转换为int16或int32,该如何保留负数值呢?
32位:
x = (x >> 11) == 0 ? x : -1 ^ 0xFFF | x;
假设x
已经是包含12位值的有符号短整型,无需条件地进行符号扩展:
x = (x << 4) >> 4;
括号仅用于理解正在发生的事情。位移运算符与其他算术和逻辑运算符一样是左结合的。这个方法之所以起作用,是因为>>
对于有符号类型来说是算术右移。这意味着,在最高有效位上,它不是将零移入,而是将MSB重复多次。
从n
位到m
位的常规符号扩展如下:
x = (x << (m - n)) >> (m - n);
显而易见的原因是,sbyte
的 m
会被限制为8,short
为16,int
为32,long
为64。再次说明,括号仅仅是美观上的需要。减法的优先级高于位移操作。
x = ( x & 0x800 ? x | 0xf000 : x );
xor
),然后与原始值进行or
运算以打开其中的位。结果基本上就是打开32位值的高20位。 - Andrew Cooper