C#: Convert Byte Array into a Float

C#: Convert Byte array into a float

Try

float myFloat = System.BitConverter.ToSingle(mybyteArray, startIndex);

Byte Array to Float Conversion C#

You can amend your float conversion function as below

    public float floatConversion(byte[] bytes)
{
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes); // Convert big endian to little endian
}
float myFloat = BitConverter.ToSingle(bytes, 0);
return myFloat;
}

Byte array to float

BitConverter.GetBytes(90); will give you the bytes for the integer value of 90. Since you want the bytes for the float value, you need to specify that:

BitConverter.GetBytes((float)90.0);

or

BitConverter.GetBytes(90.0f);

Reading byte array and converting into float in C#

Since you mentioned that the first value is 2.4 and each float is represented by 4 bytes;

byte[] data = { 64, 25, 153, 154, 66, 157, 20, 123, 66, 221, 174, 20, 65, 204, 0, 0, 65, 163, 51, 51, 66, 95, 51, 51, 69, 10, 232, 0 };

We can group the bytes into 4 byte blocks and reverse them and convert each part to float like:

int offset = 0;
float[] dataFloats =
data.GroupBy(x => offset++ / 4) // group by 4. 0/4 = 0, 1/4 = 0, 2/4 = 0, 3/4 = 0 and 4/4 = 1 etc.
// Need to reverse the bytes to make them evaluate to 2.4
.Select(x => BitConverter.ToSingle(x.ToArray().Reverse().ToArray(), 0))
.ToArray();

Now you have an array of 7 floats:

Sample Image

Byte[] to float conversion

This is working for me.

float val = (float)0.995;
Byte[] arr = BitConverter.GetBytes(val);

float myFloat = BitConverter.ToSingle(arr, 0);

convert byte array to 16 bits float

What standard you have used that gave you {0x70 , 0x54} ?

I have made a sample code for Half-precision floating point conversation according to IEEE 754-2008 standard.

https://en.wikipedia.org/wiki/Half-precision_floating-point_format

public static float toTwoByteFloat(byte HO, byte LO)
{
var intVal = BitConverter.ToInt32(new byte[] { HO, LO, 0, 0 }, 0);

int mant = intVal & 0x03ff;
int exp = intVal & 0x7c00;
if (exp == 0x7c00) exp = 0x3fc00;
else if (exp != 0)
{
exp += 0x1c000;
if (mant == 0 && exp > 0x1c400)
return BitConverter.ToSingle(BitConverter.GetBytes((intVal & 0x8000) << 16 | exp << 13 | 0x3ff), 0);
}
else if (mant != 0)
{
exp = 0x1c400;
do
{
mant <<= 1;
exp -= 0x400;
} while ((mant & 0x400) == 0);
mant &= 0x3ff;
}
return BitConverter.ToSingle(BitConverter.GetBytes((intVal & 0x8000) << 16 | (exp | mant) << 13), 0);
}

private static byte[] I2B(int input)
{
var bytes = BitConverter.GetBytes(input);
return new byte[] { bytes[0], bytes[1] };
}

public static byte[] ToInt(float twoByteFloat)
{
int fbits = BitConverter.ToInt32(BitConverter.GetBytes(twoByteFloat), 0);
int sign = fbits >> 16 & 0x8000;
int val = (fbits & 0x7fffffff) + 0x1000;
if (val >= 0x47800000)
{
if ((fbits & 0x7fffffff) >= 0x47800000)
{
if (val < 0x7f800000) return I2B(sign | 0x7c00);
return I2B(sign | 0x7c00 | (fbits & 0x007fffff) >> 13);
}
return I2B(sign | 0x7bff);
}
if (val >= 0x38800000) return I2B(sign | val - 0x38000000 >> 13);
if (val < 0x33000000) return I2B(sign);
val = (fbits & 0x7fffffff) >> 23;
return I2B(sign | ((fbits & 0x7fffff | 0x800000) + (0x800000 >> val - 102) >> 126 - val));
}

You'll use it like following

private void button1_Click(object sender, EventArgs e)
{
var x = ToInt(0.660f); //it's 0x48 0x39
var y = toTwoByteFloat(x[0], x[1]); //it's 0.66015625
}

c# convert byte array to float and divide them by value

Given 4 bytes, you would normally only "shift" (<<) if it is integer data. The code in the question basically reads the data as an int (via "shift"), then casts the int to a float. Which is almost certainly not what was intended.

Since you want to interpret it as float, you should probably use:

float val = BitConverter.ToSingle(data, offset);

where offset is the 0, 4, 8, 12 etc shown in your data + 4, data + 8, etc. This treats the 4 bytes (relative to offset) as raw IEEE 754 floating point data. For example:

float x= BitConverter.ToSingle(data, 0);
float y= BitConverter.ToSingle(data, 4);
float z= BitConverter.ToSingle(data, 8);
float alpha= BitConverter.ToSingle(data, 12);
float theta= BitConverter.ToSingle(data, 16);
float phi= BitConverter.ToSingle(data, 20);

Note that this makes assumptions about "endianness" - see BitConverter.IsLittleEndian.


Edit: from comments, it sounds like the data is other-endian; try:

public static float ReadSingleBigEndian(byte[] data, int offset)
{
if (BitConverter.IsLittleEndian)
{
byte tmp = data[offset];
data[offset] = data[offset + 3];
data[offset + 3] = tmp;
tmp = data[offset + 1];
data[offset + 1] = data[offset + 2];
data[offset + 2] = tmp;
}
return BitConverter.ToSingle(data, offset);
}
public static float ReadSingleLittleEndian(byte[] data, int offset)
{
if (!BitConverter.IsLittleEndian)
{
byte tmp = data[offset];
data[offset] = data[offset + 3];
data[offset + 3] = tmp;
tmp = data[offset + 1];
data[offset + 1] = data[offset + 2];
data[offset + 2] = tmp;
}
return BitConverter.ToSingle(data, offset);
}
...
float x= ReadSingleBigEndian(data, 0);
float y= ReadSingleBigEndian(data, 4);
float z= ReadSingleBigEndian(data, 8);
float alpha= ReadSingleBigEndian(data, 12);
float theta= ReadSingleBigEndian(data, 16);
float phi= ReadSingleBigEndian(data, 20);

If you need to optimize this massively, there are also things you can do with unsafe code to build an int from shifting (picking the endianness when shifting), then do an unsafe coerce to get the int as a float; for example (noting that I haven't checked endianness here - it might misbehave on a big-endian machine, but most people don't have those):

public static unsafe float ReadSingleBigEndian(byte[] data, int offset)
{
int i = (data[offset++] << 24) | (data[offset++] << 16) |
(data[offset++] << 8) | data[offset];
return *(float*)&i;
}
public static unsafe float ReadSingleBigEndian(byte[] data, int offset)
{
int i = (data[offset++]) | (data[offset++] << 8) |
(data[offset++] << 16) | (data[offset] << 24);
return *(float*)&i;
}

Or crazier, and CPU-safer:

public static float ReadSingleBigEndian(byte[] data, int offset)
{
return ReadSingle(data, offset, false);
}
public static float ReadSingleLittleEndian(byte[] data, int offset)
{
return ReadSingle(data, offset, true);
}
private static unsafe float ReadSingle(byte[] data, int offset,
bool littleEndian)
{
fixed (byte* ptr = &data[offset])
{
if (littleEndian != BitConverter.IsLittleEndian)
{ // other-endian; swap
byte b = ptr[0];
ptr[0] = ptr[3];
ptr[3] = b;
b = ptr[1];
ptr[1] = ptr[2];
ptr[2] = b;
}
return *(float*)ptr;
}
}

problem converting 4-bytes array to float in C#

Your bytes are coming out word-swapped. This function should convert your byte array to floats properly:

static float ToFloat(byte[] input)
{
byte[] newArray = new[] { input[2], input[3], input[0], input[1] };
return BitConverter.ToSingle(newArray, 0);
}

ToFloat(new byte[]{2,73,98,43}) == 533174.1

C# : how to convert char array into float

As suggested by shingo, the linked question provides the answer:

var input = new byte[] { 0x1F, 0x05, 0x01, 0x42 };
Console.WriteLine(BitConverter.ToSingle(input, 0)); // Outputs 32.255


Related Topics



Leave a reply



Submit