如何在Java中使用bitshifting

我正在尝试构建一个IP头。

IP头具有以下字段:版本,IHL,DSCP等。我想填充字节数组,以便我可以以字节存储信息。

然而,我感到困惑的是,Version字段只有4位宽。 国际人道法也只有4位宽。 如何将这两个字段的值拟合为一个字节? 我需要做位移吗?

例如版本= 4,IHL = 5.我需要创建一个等于0100 0101 = 45h或69十进制的字节。

(byte) (4 << 4) | 5 

这将值4向左移动,然后将低4位设置为值5。

  1. 00000100 A值( 4
  2. 01000000左移4位后( << 4
  3. 00000101另一个值( 5
  4. 01000101 #2和#3的按位OR( | )的结果

因为操作数是int类型(即使它们是byte值,当操作符喜欢它们时它们会被提升为int ),最终结果需要将转换存储在一个byte

如果在任何按位运算中使用byte值作为操作数,则隐式转换为int可能会导致意外结果。 如果要将一个byte视为在该转换中无符号,请使用按位AND( & ):

 byte b = -128; // The byte value 0x80, -128d int uint8 = b & 0xFF; // The int value 0x00000080, 128d int i = b; // The int value 0xFFFFFF80, -128d int uintr = (b & 0xFF) | 0x04; // 0x00000084 int sintr = b | 0x04; // 0xFFFFFF84 

你可以这样做:

  int a = 0x04; a <<= 4; a |= 0x05; System.out.println(a); 

它基本上将0b00000100变为0b01000000,然后变为0b01000101。

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

要在一个字节中创建包含Version和IHL的压缩字段,请尝试执行

 byte b = (byte)((Version << 4) + IHL); 

这仅适用于版本和国际人道法是0到15之间的数字

只是因为一个字节是8位而你的值最多只能是4不是问题。 额外的4位将始终为零。

因此,如果您存储1例如:

0000 0001

或15(这是最大值?):

0000 1111

在Java中不可能进行字节转换。

bithifting如何在Java中工作?

但是,就逻辑而言,如果您希望版本和​​IHL在一个字节中,您可以使用以下内容执行此操作

 byte value = (byte) (IHL | VERSION << 4);