1

我在java中面临一个关于无符号值的问题。可以请我。实际上问题是,我有一个字节缓冲区,其中放置了不同的数据类型(例如,第一个浮点数,然后是双精度数,然后是双精度数之后的整数),其中一些可能是有符号的,而另一些是无符号的。我的列表有它们的顺序和数据类型以及符号信息,所以我从字节缓冲区中读取它们并将它们直接分配给相应的变量

例如:

int i= bytebuffer.getInt();

一切都很好,但对于无符号最大值,它给出的是负值。对于 int float, double 这与我面临的问题相同。

我读到一些java不支持无符号值的地方,但我遇到了int、short到无符号值的转换,但我找不到关于double、float的信息。

编辑:我的代码是

        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。

双也同理。

请任何机构对此提供帮助。

4

3 回答 3

3

是的,Java 只有带符号的值(char 除外,它可能被视为无符号短)。

对于无符号短(例如),可以读/写短,并将其值保存在(有符号)整数中:

short x = -3; // But intended as unsigned 0xFFFD
int ux = x & 0xFFFF; // The unsigned value by masking

等等。

我第一次听到无符号双。检查二进制格式。对于有符号的java double,有一个符号位,对于无符号的double,它可能会添加到尾数中。在这种情况下,精度略有损失,应该可以进行转换。

于 2013-11-07T09:12:55.470 回答
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 解释为无符号 is = [255]

只是解释问题 - 只需按原样读取整数变量,但要打印为无符号值,请执行类似于上述操作的操作。

当然,这适用于这里的整数类型,而不适用于浮点,因为它们总是有符号的。如果你想让他们积极使用 abs 等。

于 2013-11-07T09:23:18.957 回答
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为原始类型。byteValueshortValueintValuelongValue

对于浮点类型,您可以使用BigDecimalunscaledValue()(即尾数)做一些非常相似的事情。

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

于 2013-11-07T10:38:33.923 回答