24

I have some single and double precision floats that I want to write to and read from a byte[]. Is there anything in .Net I can use to convert them to and from their 32 and 64 bit IEEE 754 representations?

mskfisher
  • 3,291
  • 4
  • 35
  • 48
HasaniH
  • 8,232
  • 6
  • 41
  • 59

2 Answers2

36

.NET Single and Double are already in IEEE-754 format. You can use BitConverter.ToSingle() and ToDouble() to convert byte[] to floating point, GetBytes() to go the other way around.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
9

Update for current .NET/C# using spans:

static void Main()
{
    Span<byte> data = stackalloc byte[20];
    GetBytes(0, data, 0);
    GetBytes(123.45F, data, 4);
    GetBytes(123.45D, data, 8);
}

static unsafe void GetBytes(float value, Span<byte> buffer, int offset)
    => MemoryMarshal.Cast<byte, float>(buffer.Slice(offset))[0] = value;
static unsafe void GetBytes(double value, Span<byte> buffer, int offset)
    => MemoryMarshal.Cast<byte, double>(buffer.Slice(offset))[0] = value;

If you don't want to allocate new arrays all the time (which is what GetBytes does), you can use unsafe code to write to a buffer directly:

static void Main()
{
    byte[] data = new byte[20];
    GetBytes(0, data, 0);
    GetBytes(123.45F, data, 4);
    GetBytes(123.45D, data, 8);
}

static unsafe void GetBytes(float value, byte[] buffer, int offset)
{
    fixed (byte* ptr = &buffer[offset])
    {
        float* typed = (float*)ptr;
        *typed = value;
    }
}
static unsafe void GetBytes(double value, byte[] buffer, int offset)
{
    fixed (byte* ptr = &buffer[offset])
    {
        double* typed = (double*)ptr;
        *typed = value;
    }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • What are the implications for doing it this way compared to creating an array? I'm interested in what happens in memory and what the GC does etc. – David Klempfner Nov 17 '19 at 01:19
  • 1
    @Backwards_Dave simply: one allocates an array, one doesn't! what GC does will depend entirely upon when that array is unreachable, but: it will need to be collected at some point. Note that in current .NET/C#, you could use a `Span` API here, and do the entire thing without any `unsafe` and without any array allocations *at all* (using a `stackalloc` span) - see edit – Marc Gravell Nov 17 '19 at 10:14