Convert float[] to byte[] to float[] again

20,204

Solution 1

I think you want to make use of the ByteBuffer class, which has putFloat and getFloat methods.

Solution 2

Another way... use ByteArrayOutputStream/DataOutputStream for output

float fArr[] = ...;
ByteArrayOutputStream bas = new ByteArrayOutputStream();
DataOutputStream ds = new DataOutputStream(bas);
for (float f : fArr) 
    ds.writeFloat(f);
byte[] bytes = bas.toByteArray();

Use ByteArrayInputStream/DataInputStream for input

byte[] buffer = ...;
ByteArrayInputStream bas = new ByteArrayInputStream(buffer);
DataInputStream ds = new DataInputStream(bas);
float[] fArr = new float[buffer.length / 4];  // 4 bytes per float
for (int i = 0; i < fArr.length; i++)
{
    fArr[i] = ds.readFloat();
}

Solution 3

Use Float.floatToIntBits() to extract the bit-value of the float as an integer, then use BigInteger.toByteArray() to make a byte[]. This can be reversed using the BigInteger constructor that takes a byte[] argument, and then Float.intBitsToFloat().

Solution 4

This is more for my future reference than anything else.

public static byte[] floatToByte(float[] input) {
    byte[] ret = new byte[input.length*4];
    for (int x = 0; x < input.length; x++) {
        ByteBuffer.wrap(ret, x*4, 4).putFloat(input[x]);
    }
    return ret;
}

public static float[] byteToFloat(byte[] input) {
    float[] ret = new float[input.length/4];
    for (int x = 0; x < input.length; x+=4) {
        ret[x/4] = ByteBuffer.wrap(input, x, 4).getFloat();
    }
    return ret;
}

Can be reduced to a single line like https://stackoverflow.com/a/44104399/322017.

Solution 5

An improvement to Steven Chou's answer

final static int BYTES_IN_FLOAT = Float.SIZE / Byte.SIZE;

public static byte[] toByteArray(float[] floatArray) {
    ByteBuffer buffer = ByteBuffer.allocate(floatArray.length * BYTES_IN_FLOAT)
    buffer.asFloatBuffer.put(floatArray);
    return buffer.array();
}


public static float[] toFloatArray(byte[] byteArray) {
    float[] result = new float[byteArray.length / BYTES_IN_FLOAT];
    ByteBuffer.wrap(byteArray).asFloatBuffer().get(result, 0, result.length);
    return result;
}
Share:
20,204
brain56
Author by

brain56

Whatcha doin' here?

Updated on September 14, 2021

Comments

  • brain56
    brain56 over 2 years

    So what I'm trying to do here is get a float[], convert it to byte[], send it through the network as a datagram packet and then convert it back to a byte[] at the receiving terminal.

    Now I know I can convert float[] to byte[] by using the getBytes[] method. But I don't know how to reverse the conversion.

  • Dawood ibn Kareem
    Dawood ibn Kareem about 12 years
    But that won't give you general float values, only those that represent whole numbers between 0 and 255. A float needs 4 bytes, and the floatValue method of the Byte class only works with one.
  • brain56
    brain56 about 12 years
    Thanks! I think this is it. I'll give it a go when I get the time and I'll let you know what happens.
  • Lie Ryan
    Lie Ryan about 12 years
    @brain56: just wanted to add that if you're sending this over a network, you would want to explicitly specify an encoding instead of leaving yourself at the mercy of the platform's default encoding.
  • pzo
    pzo over 11 years
    there is not such a method as writeFloat - your code simply doesn't compile
  • ricosrealm
    ricosrealm over 11 years
    thanks for pointing it out, I've updated the code with the correct adapter class in place.
  • Steven Magana-Zook
    Steven Magana-Zook over 9 years
    ByteBuffer also has the asFloatBuffer() method in case you do not want to extract the values individually you can chain the method calls: ByteBuffer.wrap(someByteArray).asFloatBuffer().array() to go from a byte[] to a float[]
  • Dawood ibn Kareem
    Dawood ibn Kareem over 9 years
    @StevenMagana-Zook You could post that as an answer.
  • Mohammad Kholghi
    Mohammad Kholghi over 2 years
    Can use Float.BYTES instead of Float.SIZE / Byte.SIZE
  • MA90
    MA90 over 2 years
    Float.BYTES is only available from java 8+. For older version Float.SIZE / Byte.SIZE is the way to go