2

I just got confused about how to convert an array of 4 signed bytes to a float number.

I just know for an array of unsigned bytes bts, probably I can use this function

BitConverter.ToSingle(bts, 0);

However, it looks like BitConverter.ToSingle only accepts byte array instead of sbyte array.

Could somebody give me some ideas please?

Thanks!

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
user3535716
  • 255
  • 4
  • 14
  • Because it convert object type, it doesn't convert values. Each 4 bytes will _become_ a single float value. Because bytes are just parts of float representation in memory then sign doesn't make any sense there. If you have to convert values then you have to create a new float array and to copy values there (one by one). – Adriano Repetti May 03 '14 at 11:45
  • In what way does your signed bytes represent a float? Normally 4 unsigned bytes represent one float as said below.. If you give a concrete example we can give a solution – Mattias Åslund May 03 '14 at 11:52
  • That is to say, if I got one signed array and another unsigned array but with the same bytes, theoretically they could become the same float number..... – user3535716 May 03 '14 at 11:53
  • 1
    But... How did you end up with the sbyte[]? I guess theoretically you can `BitConverter.ToSingle(bts.Select(b=>(byte)(b+128)).ToArray())` – Mattias Åslund May 03 '14 at 12:18
  • If this is about a bit represenation of a float they should never have been `sbyte` in the first place. Check your dataflow for the problem upstream. – H H May 03 '14 at 12:54
  • @user I cannot see how the answer you accepted relates to the question you asked. – David Heffernan May 04 '14 at 12:09

5 Answers5

1

Maybe this:

float num = 0;

for (int i = 0; i < sbytesArr.Length; i++)
{
     num = (num | sbytesArr[i]) << i * 4;
}
Lynx
  • 506
  • 2
  • 10
1
    Float value = 5000.1234;
//
// Invoke BitConverter.GetBytes to convert double to bytes.
//
byte[] array = BitConverter.GetBytes(value);
foreach (byte element in array)
{
    Console.WriteLine(element);
}
//
// You can convert the bytes back to a double.
//
Float result = BitConverter.Tofloat(array, 0);
Console.WriteLine(result);
Kumar Manish
  • 3,746
  • 3
  • 37
  • 42
1

Assuming that your signed bytes are in an array named sbts you can first of all convert to an unsigned byte array, and then use BitConverter.ToSingle().

byte[] bts = new byte[sbts.Length];
Buffer.BlockCopy(sbts, 0, bts, 0, sbts.Length);
float f = BitConverter.ToSingle(bts, 0);
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

It is a little known fact that byte and sbyte are interchangeable at the CLR level:

sbyte[] a = new sbyte[1];
byte[] b = (byte[])(object)a;

This code actually works at runtime. So can pass in the array that you have.

BitConverter.ToSingle((byte[])(object)bts, 0);
Community
  • 1
  • 1
usr
  • 168,620
  • 35
  • 240
  • 369
  • There is some more discussion of this technique here: http://stackoverflow.com/questions/829983/how-to-convert-a-sbyte-to-byte-in-c I think the key comment made there is: *What this does is change the compile-time type of the array. Useful technique, but it depends what ends up consuming the result. For instance, `System.Array.Copy(Array, int, Array, int, int)` looks at the runtime-type of the two arrays and will throw an exception if you try to copy a "real" byte[] to a `sbyte[]` masquerading as a `byte[]`.* – David Heffernan May 03 '14 at 12:17
0

Call GetFloatValue method passing una array of four sbyte as parameter

    public float GetFloatValue(sbyte[] data)
    {
        return bytesToFloat(data[0], data[1], data[2], data[3]);
    }

    private static float bytesToFloat(sbyte b0, sbyte b1, sbyte b2, sbyte b3)
    {
        int mantissa = (byte)b0 + ((byte)b1 << 8) + ((byte)b2 << 16);
        return (float)(mantissa * Math.Pow(10, b3));
    }
Giuseppe Laera
  • 272
  • 2
  • 14