是否将两个字节转换为12位的short值?

时间:2018-07-03 15:01:13

标签: c++ casting

我有一个缓冲区,该缓冲区由无符号char数据和两个字节组成一个12位值。

我发现我的系统是小端的。缓冲区中的第一个字节为我提供了从0到255的控制台编号。第二个字节始终为1到8之间的低编号(测量数据,因此也可能有更高的值,最高可达4位)。

我试图将它们移到一起,以便获得带有正确12位数字的ushort。

可悲的是,此刻,我完全感到困惑,因为我对字节序的不确定性以及必须朝哪个方向移动多远。

我尝试过这个:

ushort value =0;
value= (ushort) firstByte << 8 | (ushort) secondByte << 4;

可悲的是,value的值通常大于12位。

哪里出了错?

2 个答案:

答案 0 :(得分:6)

这取决于如何将位精确地打包在两个字节中,但是最可能打包的解决方案是:

value = firstByte | (secondByte << 8);

这假定第二个字节包含4个最高有效位(位8..11),而第一个字节包含8个最低有效位(位0..7)。


注意:以上解决方案假定firstBytesecondByte是明智的无符号类型(例如uint8_t)。如果不是(例如,如果您使用过char或其他可能带有符号的类型),则需要添加一些遮罩:

value = (firstByte & 0xff) | ((secondByte & 0xf) << 8);

答案 1 :(得分:0)

我认为主要问题可能不在于您独自转移的价值观。如果这些值大于它们的代表位,除非“和”出来,否则它们将创建一个大值。

图片如下

0000 0000 1001 0010 << 8 | 0000 0000 0000 1101 << 4
1001 0010 0000 0000 | 0000 0000 1101 0000

您应该在这里注意到第一个问题。前4个“最低”值未使用,它使用了16位。你只想要十二个应该这样修改:

(these are new numbers to demonstrate something else)
0000 1101 1001 0010 << 8 | 0000 0000 0000 1101
1101 1001 0010 0000 | (0000 0000 0000 1101 & 0000 0000 0000 1111)

这将创建以下值:

1101 1001 0010 1101 

在这里,您应该注意该值仍大于12位。如果您的数字没有扩展通过原始的8位,则忽略4位大小。否则,您必须对这些位使用“和”运算以消除最左边的4位。

0000 1111 1111 1111 & 0000 1001 0010 1101

可以使用0bXX宏,2 ^ bits-1模式以及各种其他形式来创建这些值。