我遇到了关于java中无符号值的问题。可以请任何请我。 实际上问题是,我有一个字节缓冲区,其中放置了不同的数据类型(例如,第一个浮点数然后是一个双精度数,然后是双精度数之后的一个int),其中一些可能是有符号的,一些是无符号的。我正在列表中有他们的订单和数据类型以及签名信息,所以我从bytebuffer中读取它们并直接将它们分配给相应的变量
例如:
int i= bytebuffer.getInt();
每件事都很好但是对于无符号的最大值,它给出了负值。对于int float,double,这与我面临的问题相同。
我读了一些java不支持无符号值的地方,但是我遇到了int的转换,short转换为无符号值,但是我无法找到关于double的浮点数。
编辑: 我的代码是
File file= new File("blob_960");
int count,length;
length = (int)(file.length());
count=(length/380);
ByteBuffer bytebufr= ByteBuffer.allocate(length);
bytebufr.order(ByteOrder.LITTLE_ENDIAN);
byte[] bytes= new byte[length];
FileInputStream fis = new FileInputStream(file);
fis.read(bytes,0, length);
bytebufr.put(bytes);
bytebufr.position(0);
int i = bytebufr.getInt();
float f = bytebufr.getFloat();
double d = bytebufr.getDouble();
示例 - 字节值是220 我正在使用
读取字节 byte b = bytebufr.get();
System.out.println(b); // this is giving -36
// I am expecting 220.
Binary value of 220 is -11011100
Binary value of -36 is -11011100
它将值视为有符号值并给出-36,但该值未签名且我预计为220.
与双倍相同。
任何人都请帮忙。
答案 0 :(得分:3)
是的,Java只有签名值(char除外,可能被视为无符号短)。
对于unsigned short(例如),可以读取/写入short,并将其值保存在(signed)int中:
short x = -3; // But intended as unsigned 0xFFFD
int ux = x & 0xFFFF; // The unsigned value by masking
等等。
无符号双人我第一次听到。检查二进制格式。 对于带符号的java double,有一个符号位,可能是对于无符号双重添加到mantisse。在这种情况下,如果精度略有下降,则应该可以进行转换。
答案 1 :(得分:0)
二进制数据的解释方式完全取决于您 - 如果您希望将8位值作为无符号处理/打印(在java中),只需将其转换为更长的值,从而删除因符号扩展而可能出现的额外位 - 例如,的是:
byte b = (byte) 0xFF;
int i = ((int)b) & 0xff;
System.out.println("b=[" + b + "] b interpreted as unsigned is = [" + i + "]");
的产率:
b = [ - 1] b被解释为无符号= [255]
只是解释问题 - 只需按原样读取整数变量,但是对于打印,无符号值执行与上述类似的操作。
当然这适用于整数类型而不是浮点数,因为它们总是被签名。如果你想要他们积极使用abs等。
答案 2 :(得分:0)
这是你在BigInteger
的帮助下阅读任意长度的有符号/无符号整数的方法:
public static void main(String[] args) {
final byte FULL_BYTE = (byte) 0xFF;
ByteBuffer buffer = ByteBuffer.wrap(new byte[] { FULL_BYTE, FULL_BYTE, FULL_BYTE, FULL_BYTE });
System.out.println(readSignedInteger(buffer, 4, true)); // => -1
buffer.rewind();
System.out.println(readUnsignedInteger(buffer, 4, true)); // => 4294967295
buffer.rewind();
System.out.println(readSignedInteger(buffer, 2, true)); // => -1
buffer.rewind();
System.out.println(readUnsignedInteger(buffer, 2, true)); // => 65535
}
public static BigInteger readUnsignedInteger(ByteBuffer buffer, int length, boolean littleEndian) {
return new BigInteger(1, readBytes(buffer, length, littleEndian));
}
public static BigInteger readSignedInteger(ByteBuffer buffer, int length, boolean littleEndian) {
return new BigInteger(readBytes(buffer, length, littleEndian));
}
public static byte[] readBytes(ByteBuffer buffer, int length, boolean reversed) {
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
bytes[reversed ? length - 1 - i : i] = buffer.get();
}
return bytes;
}
您可以通过BigInteger
,byteValue
,shortValue
,intValue
方法将longValue
转换为原始类型。
对于浮点类型,您可以使用BigDecimal
及其unscaledValue()
(即尾数)执行非常类似的操作。
请注意,您将无法将 unsigned long 和 unsigned double 转换为任何相应的基本类型(因为Java中没有)。