如何在 Java 中使用移位
How to use bitshifting in Java
我正在尝试构建 IP header。
IP header 具有以下字段:版本、IHL、DSCP 等。我想填充一个字节数组,以便我可以以字节为单位存储信息。
然而,令我感到困惑的是 Version 字段只有 4 位宽。国际人道法也只有 4 位宽。我如何将这两个字段的值都表示为一个字节?我需要进行位移吗?
例如版本 = 4,IHL = 5。我需要创建一个等于 0100 0101 = 45h 或十进制 69 的字节。
仅仅因为一个字节是 8 位并且您的值最多只能是 4 不是问题。额外的 4 位将始终为零。
因此,如果您要存储 1,例如:
0000 0001
或15(哪个是最大值对吧?):
0000 1111
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
要在一个字节中制作一个包含版本和 IHL 的紧凑字段,请尝试这样做
byte b = (byte)((Version << 4) + IHL);
仅当 Version 和 IHL 是 0 到 15 之间的数字时才有效
你可以这样做:
int a = 0x04;
a <<= 4;
a |= 0x05;
System.out.println(a);
基本上将 0b00000100 变成 0b01000000,然后变成 0b01000101。
Java 中无法进行字节移位。
How does bitshifting work in Java?
但是,就逻辑而言,如果你想要一个字节的版本和国际人道法,你可以使用下面的方法
byte value = (byte) (IHL | VERSION << 4);
(byte) (4 << 4) | 5
这会将值 4 左移,然后将低 4 位设置为值 5。
00000100
一个值 (4
)
01000000
左移4位后(<< 4
)
00000101
另一个值 (5
)
01000101
#2 和 #3 按位或 (|
) 的结果
因为操作数是 int
类型(即使它们是 byte
值,当像 |
这样的运算符作用于它们时,它们也会被提升为 int
), 最终结果需要一个cast存储在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
我正在尝试构建 IP header。
IP header 具有以下字段:版本、IHL、DSCP 等。我想填充一个字节数组,以便我可以以字节为单位存储信息。
然而,令我感到困惑的是 Version 字段只有 4 位宽。国际人道法也只有 4 位宽。我如何将这两个字段的值都表示为一个字节?我需要进行位移吗?
例如版本 = 4,IHL = 5。我需要创建一个等于 0100 0101 = 45h 或十进制 69 的字节。
仅仅因为一个字节是 8 位并且您的值最多只能是 4 不是问题。额外的 4 位将始终为零。
因此,如果您要存储 1,例如:
0000 0001
或15(哪个是最大值对吧?):
0000 1111
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
要在一个字节中制作一个包含版本和 IHL 的紧凑字段,请尝试这样做
byte b = (byte)((Version << 4) + IHL);
仅当 Version 和 IHL 是 0 到 15 之间的数字时才有效
你可以这样做:
int a = 0x04;
a <<= 4;
a |= 0x05;
System.out.println(a);
基本上将 0b00000100 变成 0b01000000,然后变成 0b01000101。
Java 中无法进行字节移位。
How does bitshifting work in Java?
但是,就逻辑而言,如果你想要一个字节的版本和国际人道法,你可以使用下面的方法
byte value = (byte) (IHL | VERSION << 4);
(byte) (4 << 4) | 5
这会将值 4 左移,然后将低 4 位设置为值 5。
00000100
一个值 (4
)01000000
左移4位后(<< 4
)00000101
另一个值 (5
)01000101
#2 和 #3 按位或 (
|
) 的结果
因为操作数是 int
类型(即使它们是 byte
值,当像 |
这样的运算符作用于它们时,它们也会被提升为 int
), 最终结果需要一个cast存储在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