【问题标题】:How to read an unsigned double value from ByteBuffer如何从 ByteBuffer 读取无符号双精度值
【发布时间】:2013-11-07 09:03:26
【问题描述】:

我遇到了一个关于 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。

double 也一样。

请任何机构帮忙。

【问题讨论】:

  • 请向我们展示您的代码。
  • 无符号整数---我听说过。但是无符号双?这是第一次。
  • 什么不适用于getDouble()?你会得到什么,你期望什么?
  • 无符号双精度不是由 IEEE 标准指定的,所以无论你有什么,它都是非标准的,因此在 JDK 或任何其他标准库中不受支持。
  • 不存在无符号浮点(在这种情况下为双精度)

标签: java unsigned bytebuffer


【解决方案1】:

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

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

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

等等。

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

【讨论】:

    【解决方案2】:

    如何解释二进制数据完全取决于您 - 如果您希望 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 等。

    【讨论】:

      【解决方案3】:

      这是您在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;
      }
      

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-21
        相关资源
        最近更新 更多