如何从ByteBuffer中读取unsigned double值

时间:2013-11-07 09:03:27

标签: java unsigned bytebuffer

我遇到了关于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.

与双倍相同。

任何人都请帮忙。

3 个答案:

答案 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;
}

您可以通过BigIntegerbyteValueshortValueintValue方法将longValue转换为原始类型。

对于浮点类型,您可以使用BigDecimal及其unscaledValue()(即尾数)执行非常类似的操作。

请注意,您将无法将 unsigned long unsigned double 转换为任何相应的基本类型(因为Java中没有)。