sta*_*low 8 java bit-manipulation
我正在解析DatagramSocket中的无符号位.我总共有24位(或3个字节)进入 - 它们是:1个无符号8位整数,后跟16位有符号整数.但java永远不会将有符号的字节存储到字节/字节数组中?当java接收这些值时,你会丢失最后的第8位吗?
DatagramSocket serverSocket = new DatagramSocket(666);
byte[] receiveData = new byte[3]; <--Now at this moment I lost my 8th bit
System.out.println("Binary Server Listing on Port: "+port);
while (true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
byte[] bArray = receivePacket.getData();
byte b = bArray[0];
}
Run Code Online (Sandbox Code Playgroud)

自从我把它变成一个字节后,我现在失去了第8位吗?是不是我初始化了一个3字节的字节数组?
Jon*_*eet 12
当java接收这些值时,你会丢失最后的第8位吗?
不,你设置时最终会得到一个负值.
因此要获得0到255之间的值,最简单的方法是使用以下内容:
int b = bArray[0] & 0xff;
Run Code Online (Sandbox Code Playgroud)
首先将byte其提升为a int,将对其进行符号扩展,如果原始值中的高位为1,则导致25个前导1位.在& 0xff随后摆脱又是第24位的:)
不,你不会失去第8位.但不幸的是,Java有两个"功能",这使得处理这些值变得比合理更难:
byte到int这里的情况),"较低类型"的符号位被扩展.这意味着,例如,如果您读取byte 0x80,则将二进制转换为:
1000 0000
Run Code Online (Sandbox Code Playgroud)
当你把它读成一个整数时,你得到:
1111 1111 1111 1111 1111 1111 1000 0000
^
This freaking bit gets expanded!
Run Code Online (Sandbox Code Playgroud)
而你真的想要:
0000 0000 0000 0000 0000 0000 1000 0000
Run Code Online (Sandbox Code Playgroud)
即,整数值128.因此你必须掩盖它:
int b = array[0] & 0xff;
1111 1111 1111 1111 1111 1111 1000 0000 <-- byte read as an int, your original value of b
0000 0000 0000 0000 0000 0000 1111 1111 <-- mask (0xff)
--------------------------------------- <-- anded, give
0000 0000 0000 0000 0000 0000 1000 0000 <-- expected result
Run Code Online (Sandbox Code Playgroud)
悲伤,但是真的.
更一般地说:如果你想操纵很多面向字节的数据,我建议你看看ByteBuffer,它可以帮到很多.但不幸的是,这不会让你免于位掩码操作,只是它使得更容易读取给定数量的字节作为时间(作为基本类型).