4

Which is the fastest way to convert a byte[] to float[] and vice versa (without a loop of course).

I'm using BlockCopy now, but then I need the double memory. I would like some kind of cast.

I need to do this conversion just to send the data through a socket and reconstruct the array in the other end.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pedro77
  • 5,176
  • 7
  • 61
  • 91
  • Do you mean: 1 byte => 1 float or 4 bytes => 1 float? – user703016 Aug 01 '11 at 20:02
  • Could you please state why you want to do this, and exactly what you want to use it for? That would make it easier to come up with good solutions. There are many interesting hacks mentioned in answers, but, depending on what you actually what you wish to achieve, some may, and some may not, give you the results you want. – Erik A. Brandstadmoen Aug 01 '11 at 22:08
  • ok! You are right, I have just edited the question – Pedro77 Aug 03 '11 at 11:34

4 Answers4

7

Surely msarchet's proposal makes copies too. You are talking about just changing the way .NET thinks about a memory area, if you dont' want to copy.

But, I don't think what you want is possible, as bytes and floats are represented totally different in memory. A byte uses exactly a byte in memory, but a float uses 4 bytes (32 bits).

If you don't have the memory requirements to store your data, just represent the data as the data type you will be using the most in memory, and convert the values you actually use, when you use them.

How do you want to convert a float (which can represent a value between ±1.5 × 10−45 and±3.4 × 10^38) into a byte (which can represent a value between 0 and 255) anyway?

(see more info her about:

More about floating types in .NET here: http://csharpindepth.com/Articles/General/FloatingPoint.aspx

Erik A. Brandstadmoen
  • 10,430
  • 2
  • 37
  • 55
  • Then I guess storing them in a struct-like layout is the best, as Phillipp Schmid has proposed. More discussion about that here: http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/60150e7b-665a-49a2-8e2e-2097986142f3 – Erik A. Brandstadmoen Aug 03 '11 at 12:53
4

You can use StructLayout to achieve this (from Stack Overflow question C# unsafe value type array to byte array conversions):

[StructLayout(LayoutKind.Explicit)]
struct UnionArray
{
    [FieldOffset(0)]
    public Byte[] Bytes;

    [FieldOffset(0)]
    public float[] Floats;
}

static void Main(string[] args)
{
    // From bytes to floats - works
    byte[] bytes = { 0, 1, 2, 4, 8, 16, 32, 64 };
    UnionArray arry = new UnionArray { Bytes = bytes };
    for (int i = 0; i < arry.Bytes.Length / 4; i++)
        Console.WriteLine(arry.Floats[i]);
}
Community
  • 1
  • 1
Philipp Schmid
  • 5,778
  • 5
  • 44
  • 66
0
IEnumerable<float> ToFloats(byte[] bytes)
{
  for(int i = 0; i < bytes.Length; i+=4)
     yield return BitConverter.ToSingle(bytes, i);
}
Evan Machusak
  • 694
  • 4
  • 9
  • You are using for and converting the data, I dont want to convert from byte to float, I want something like *byte = &float[0] – Pedro77 Aug 03 '11 at 11:30
-1

Two ways if you have access to LINQ:

var floatarray = ByteArry.AsEnumerable.Cast<float>().ToArray();

or just using Array Functions

var floatarray = Array.ConvertAll(ByteArray, item => (float)item);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
msarchet
  • 15,104
  • 2
  • 43
  • 66
  • OP says "without a loop". Both of your options have a hidden loop. The first actually has 2. Also neither will be as optimized BlockCopy. – Brook Aug 01 '11 at 19:50
  • Brook, you are right. And this method will actualy use 1 loat space to store each byte, it is a waste of space and I dont need that. I nedd to do this convertion just to send through a socket and reconstruct the array in the other end. – Pedro77 Aug 03 '11 at 11:28