Java:字節到浮點數/整數 (Java: Bytes to floats / ints)


問題描述

Java:字節到浮點數/整數 (Java: Bytes to floats / ints)

I have a byte array sent via UDP from x‑plane. The bytes (4) are all floats or integers… I tried to cast them to floats but no luck so far…

Example array:     byte data[41] = {‑66,30,73,0};

How do I convert 4 bytes into int or float and doesn't float use 8 bytes?

‑‑‑‑‑

參考解法

方法 1:

Note: I recommend @Ophidian's ByteBuffer approach below, it's much cleaner than this.  However this answer can be helpful in understanding the bit arithmetic going on.

I don't know the endianness of your data.  You basically need to get the bytes into an int type depending on the order of the bytes, e.g.:

int asInt = (bytes[0] & 0xFF) 
            | ((bytes[1] & 0xFF) << 8) 
            | ((bytes[2] & 0xFF) << 16) 
            | ((bytes[3] & 0xFF) << 24);

Then you can transform to a float using this:

float asFloat = Float.intBitsToFloat(asInt);

This is basically what DataInputStream does under the covers, but it assumes your bytes are in a certain order.

Edit ‑ On Bitwise OR

The OP asked for clarification on what bitwise OR does in this case.  While this is a larger topic that might be better researched independently, I'll give a quick brief.  Or (|) is a bitwise operator whose result is the set of bits by individually or‑ing each bit from the two operands.

E.g. (in binary)

   10100000
|  10001100
‑‑‑‑‑‑‑‑‑‑‑
   10101100

When I suggest using it above, it involves shifting each byte into a unique position in the int.  So if you had the bytes {0x01, 0x02, 0x03, 0x04}, which in binary is {00000001, 00000010, 00000011, 00000100}, you have this:

                                  0000 0001   (1)
                        0000 0010             (2 <<  8)
              0000 0011                       (3 << 16)
  | 0000 0100                                 (4 << 24)
  ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
    0000 0100 0000 0011 0000 0010 0000 0001   (67 305 985)

When you OR two numbers together and you know that no two corresponding bits are set in both (as is the case here), bitwise OR is the same as addition.

See Also

  • Wikipedia: Bitwise OR

方法 2:

You probably want to make use of java.nio.ByteBuffer.  It has a lot of handy methods for pulling different types out of a byte array and should also handle most issues of endianness for you (including switching the byte order if necessary).  

byte[] data = new byte[36]; 
//... populate byte array...

ByteBuffer buffer = ByteBuffer.wrap(data);

int first = buffer.getInt();
float second = buffer.getFloat();

It also has fancy features for converting your byte array to an int array (via an IntBuffer from the asIntBuffer() method) or float array (via a FloatBuffer from the asFloatBuffer() method) if you know that the input is really all of one type.

方法 3:

Use a DataInputStream as follows:

    DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
    float f = dis.readFloat();

    //or if it's an int:        
    int i = dis.readInt();

方法 4:

You cannot just cast them into a float/int. You have to convert the bytes into an int or float.

Here is one simple way to do it:

byte [] data = new byte[] {1,2,3,4};
ByteBuffer b = ByteBuffer.wrap(data);
System.out.println(b.getInt());
System.out.println(b.getFloat());

There is a reasonable discussion here:

http://www.velocityreviews.com/forums/t129791‑convert‑a‑byte‑array‑to‑a‑float.html

方法 5:

In my opinion the ByteBuffer approach is better, you can specify where the data is wrapped (from which byte index, here 0) and also the endianness (here BIG_ENDIAN).

try {
    float result = ByteBuffer.wrap(data, 0, 4).order(BIG_ENDIAN).getFloat();
} catch (IndexOutOfBoundsException exception) {
    // TODO: handle exception
}

Functions similar to getFloat() exist for Int, Short, Long...

(by JNKMark PetersOphidiandogbaneVilasArnaud SmartFun)

參考文件

  1. Java: Bytes to floats / ints (CC BY‑SA 3.0/4.0)

#bytearray #java #integer #casting #floating-point






相關問題

更改創建 XML 閱讀器時使用的 XmlDictionaryReaderQuotas 對象的 MaxArrayLength 屬性 (Changing the MaxArrayLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader)

將文件讀入 4 個字節的 ByteArrays (Read file into ByteArrays of 4 bytes)

使用套接字 (C#) 進行文件傳輸 - 接收到的文件不包含完整數據 (File transfer using sockets (C#) - received file doesn't contain full data)

將 Java 字節讀取器轉換為 InputStream (Converting a Java byte reader to an InputStream)

用 bigInteger 和其他方法重建字節數組 (Rebuild byte array with bigInteger and other method)

如何將字節數組作為參數發送到 HTML.Action? (How to send byte array as paramater to HTML.Action?)

如何將存儲在字節數組中的圖像加載到 WebView? (How to load an image stored in a byte array to WebView?)

我希望將畫布保存為 mySql blob 字段中的 blob (I am looking to save a canvas as a blob in mySql blob field)

將字節數組的部分轉換為整數值 (Converting sections of byte arrays to integer values)

從內存中釋放 jni 引用 (Freeing jni references from memory)

為什麼 JPGEncoded bytearray 從 AS3 發送到 AMFPHP 會導致圖像無效? (Why is JPGEncoded bytearray sent from AS3 to AMFPHP resulting in an invalid image?)

Java:字節到浮點數/整數 (Java: Bytes to floats / ints)







留言討論