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:
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
How to Use Default Serialization in a Custom System.Text.JSON JSONconverter
.Net and Bitmap Not Automatically Disposed by Gc When There Is No Memory Left
Static Binding Doesn't Update When Resource Changes
How to Crop a Polygonal Area from an Image in a Winform Picturebox
.Net Regex Matching $ with the End of the String and Not of Line, Even with Multiline Enabled
Camera.Main Is Null When Performing Raycast
Using Prepared Statement in C# with MySQL
Center Multiple Rows of Controls in a Flowlayoutpanel
An Object Reference Is Required for the Non-Static Field, Method, or Property
C#: How to Get an Object by the Name Stored in String
Unrolled Loop Works, for Loop Does Not Work
Persist Data by Programming Against Interface
Can't Change Gameobject Color via Script
Get Text/Value from Textbox After Value/Text Changed Server Side
Possible Unintended Reference Comparison
Newtonsoft JSON.Net Deserialization Error Where Fields in JSON Change Order