How do I convert an array of floats to a byte[] and back?
Solution 1
If you're looking for performance then you could use Buffer.BlockCopy
. Nice and simple, and probably about as fast as you'll get in managed code.
var floatArray1 = new float[] { 123.45f, 123f, 45f, 1.2f, 34.5f };
// create a byte array and copy the floats into it...
var byteArray = new byte[floatArray1.Length * 4];
Buffer.BlockCopy(floatArray1, 0, byteArray, 0, byteArray.Length);
// create a second float array and copy the bytes into it...
var floatArray2 = new float[byteArray.Length / 4];
Buffer.BlockCopy(byteArray, 0, floatArray2, 0, byteArray.Length);
// do we have the same sequence of floats that we started with?
Console.WriteLine(floatArray1.SequenceEqual(floatArray2)); // True
Solution 2
There's the BitConverter.ToSingle(byte[] value, int startIndex)
method that should help out here.
Returns a single-precision floating point number converted from four bytes at a specified position in a byte array.
Your probably want something like (untested):
static float[] ConvertByteArrayToFloat(byte[] bytes)
{
if(bytes == null)
throw new ArgumentNullException("bytes");
if(bytes.Length % 4 != 0)
throw new ArgumentException
("bytes does not represent a sequence of floats");
return Enumerable.Range(0, bytes.Length / 4)
.Select(i => BitConverter.ToSingle(bytes, i * 4))
.ToArray();
}
EDIT: Non-LINQ:
float[] floats = new float[bytes.Length / 4];
for (int i = 0; i < bytes.Length / 4; i++)
floats[i] = BitConverter.ToSingle(bytes, i * 4);
return floats;
Solution 3
You are not moving the position when you copy the float[i] into the byte array, you should write something like
Array.Copy(BitConverter.GetBytes(float[i]),0,res,i*4);
instead of just:
ret = BitConverter.GetBytes(floats[i]);
the inverse function follow the same strategy.
Solution 4
static float[] ConvertByteArrayToFloat(byte[] bytes)
{
if(bytes.Length % 4 != 0) throw new ArgumentException();
float[] floats = new float[bytes.Length/4];
for(int i = 0; i < floats.Length; i++)
{
floats[i] = BitConverter.ToSingle(bytes, i*4);
}
return floats;
}
makerofthings7
Updated on July 09, 2022Comments
-
makerofthings7 almost 2 years
I have an array of Floats that need to be converted to a byte array and back to a float[]... can anyone help me do this correctly?
I'm working with the bitConverter class and found myself stuck trying to append the results.
The reason I'm doing this is so I can save runtime values into a IO Stream. The target storage is Azure Page blobs in case that matters. I don't care about what endian this is stored in, as long as it input matches the output.
static byte[] ConvertFloatToByteArray(float[] floats) { byte[] ret = new byte[floats.Length * 4];// a single float is 4 bytes/32 bits for (int i = 0; i < floats.Length; i++) { // todo: stuck...I need to append the results to an offset of ret ret = BitConverter.GetBytes(floats[i]); } return ret; } static float[] ConvertByteArrayToFloat(byte[] bytes) { //to do }
-
makerofthings7 over 13 yearsI love linq as much as I don't understand it! Which is a lot! Since this will be a critical performance function, I'd like to use a system level object if possible. Also the extension .ToArray() doesn't seem to exist in my .NET 4 command line project. Do you know the namespace?
-
Ani over 13 years@makerofthings7: It's in
System.Linq.Enumerable
. -
R. Martinho Fernandes over 13 years@maker:
System.Linq
, as always. -
makerofthings7 over 13 years@marthinho Yes, have System.Linq but ToArray() didn't appear. Odd
-
Ani over 13 years@makerofthings7: I was missing a parenthesis (fixed). That might have been the problem. Try now? Also, you might want to use the non-LINQ version if this is performance-critical. Profile both. :)
-
makerofthings7 over 13 yearslast parameter is 4 for Array.Copy. +1 I would mark this as the answer to the question (since it addresses the question in the title), but Ani gave so much time into his answer. Only a 5 point difference anyway...
-
Nicholas Terry over 10 yearsAwesome solution!!!!! I was going to multiply the float by like 10000000 and shift it, thus losing some precision. This is even better!
-
heltonbiker over 5 yearsInstead of a literal
4
you can usesizeof(float)
. -
El Marce over 2 years@NicholasTerry if you ever find yourself in the position of having to take the low-level road, instead of multiplying by a million, you can also store the float in its bit representation: en.wikipedia.org/wiki/Single-precision_floating-point_format