我正在分析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];
}
自从我把它变成一个字节后,我现在丢失了第8位了吗?我初始化了一个3字节的字节数组,这不对吗?
3条答案
按热度按时间qoefvg9y1#
不,你没有失去第8位。但不幸的是,java有两个“特性”,这使得处理这些值变得不合理:
它的所有基元类型都是有符号的;
将一个基元类型“展开”为另一个较大的基元类型时(例如,读取
byte
到一个int
与这里的情况一样,“lower type”的符号位被展开。这意味着,例如,如果你读byte
0x80
,二进制翻译为:当您将其读取为整数时,您将得到:
而你真正想要的是:
即,整数值128。因此,你必须掩盖它:
悲伤,但真实。
更一般地说:如果您希望操作大量面向字节的数据,我建议您看看bytebuffer,它会有很大帮助。但不幸的是,这并不能使您免于位掩码操作,它只是使您更容易一次读取给定数量的字节(作为基本类型)。
xpszyzbs2#
当java接受这些值时,会丢失最后的第8位吗?
不,当它被设置时,你只会得到一个负值。
所以要得到一个介于0和255之间的值,最简单的方法是使用以下内容:
首先
byte
被提升为int
,它将对其进行符号扩展,如果原始值中的高位为1,则导致25个前导1位。这个& 0xff
然后再去掉前24位:)w51jfk4q3#
在java中,byte(以及short、int和long)只是一种有符号的数字数据类型。但是,这并不意味着在将它们视为无符号二进制数据时会丢失任何数据。如图所示,
10000000
是-128
作为有符号的十进制数。如果您处理的是二进制数据,只需将其视为二进制形式即可。