2011-01-08 10 views
30

Ho una matrice di Float che devono essere convertiti in un array di byte e tornare a un float [] ... qualcuno può aiutarmi a farlo correttamente?Come posso convertire un array di float in un byte [] e viceversa?

Sto lavorando con la classe bitConverter e mi sono trovato bloccato cercando di aggiungere i risultati.

Il motivo per cui sto facendo questo è che posso salvare i valori di runtime in un flusso IO. La memoria di destinazione è un BLOB della pagina di Azure nel caso in cui ciò sia importante. Non mi interessa sapere in quale endian è archiviato, purché l'input corrisponda all'output.

static byte[] ConvertFloatToByteArray(float[] floats) 
     { 
      byte[] ret = new byte[floats.Length * 4];// a single float is 4 bytes/32 bits 

      for (int i = 0; i < floats.Length; i++) 
      { 
       // todo: stuck...I need to append the results to an offset of ret 
       ret = BitConverter.GetBytes(floats[i]); 

      } 
      return ret; 
     } 


static float[] ConvertByteArrayToFloat(byte[] bytes) 
{ //to do } 
+0

Si può lavorare con serializzazione/deserializzazione a/da un flusso di memoria? Si potrebbe quindi ottenere la matrice 'byte' dal flusso o costruire un flusso da una matrice' byte'. –

+0

Utilizzo dei metodi di serializzazione .Net? Preferirei non includere alcun XML e solo prendere un bit-data grezzo ... il sistema è piuttosto ottimizzato e ogni bit è rappresentato per ... – LamonteCristo

+0

puoi eseguire la serializzazione binaria invece della serializzazione XML: http: // msdn .microsoft.com/it/us/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx –

risposta

57

Se stai cercando prestazioni, è possibile utilizzare Buffer.BlockCopy. Bello e semplice, e probabilmente tanto veloce quanto il codice gestito.

var floatArray1 = new float[] { 123.45f, 123f, 45f, 1.2f, 34.5f }; 

// create a byte array and copy the floats into it... 
var byteArray = new byte[floatArray1.Length * 4]; 
Buffer.BlockCopy(floatArray1, 0, byteArray, 0, byteArray.Length); 

// create a second float array and copy the bytes into it... 
var floatArray2 = new float[byteArray.Length/4]; 
Buffer.BlockCopy(byteArray, 0, floatArray2, 0, byteArray.Length); 

// do we have the same sequence of floats that we started with? 
Console.WriteLine(floatArray1.SequenceEqual(floatArray2)); // True 
+0

Impressionante soluzione !!!!! Stavo per moltiplicare il float di 10000000 e spostarlo, perdendo così una certa precisione. Questo è ancora meglio! – nterry

3

C'è il metodo BitConverter.ToSingle(byte[] value, int startIndex) che dovrebbe aiutare qui.

restituisce una singola precisione floating numero punto convertito da quattro byte in una posizione specifica in un byte matrice.

tuo probabilmente vogliono qualcosa di simile (non testata):

static float[] ConvertByteArrayToFloat(byte[] bytes) 
{ 
    if(bytes == null) 
     throw new ArgumentNullException("bytes"); 

    if(bytes.Length % 4 != 0) 
     throw new ArgumentException 
       ("bytes does not represent a sequence of floats"); 

    return Enumerable.Range(0, bytes.Length/4) 
        .Select(i => BitConverter.ToSingle(bytes, i * 4)) 
        .ToArray(); 
} 

EDIT: non LINQ:

float[] floats = new float[bytes.Length/4]; 

for (int i = 0; i < bytes.Length/4; i++) 
    floats[i] = BitConverter.ToSingle(bytes, i * 4); 

return floats; 
+0

Amo linq tanto quanto non lo capisco! Che è molto! Poiché questa sarà una funzione di prestazioni critiche, mi piacerebbe utilizzare un oggetto a livello di sistema, se possibile. Anche l'estensione .ToArray() non sembra esistere nel mio progetto della riga di comando .NET 4. Conosci lo spazio dei nomi? – LamonteCristo

+2

per migliorare la leggibilità Sostituire i * 4 con i * sizeof (float) – BrokenGlass

+0

@ makerofthings7: È in 'System.Linq.Enumerable'. – Ani

1
static float[] ConvertByteArrayToFloat(byte[] bytes) 
{ 
    if(bytes.Length % 4 != 0) throw new ArgumentException(); 

    float[] floats = new float[bytes.Length/4]; 
    for(int i = 0; i < floats.Length; i++) 
    { 
     floats[i] = BitConverter.ToSingle(bytes, i*4); 
    } 

    return floats; 
} 
4

Non si muovono la posizione quando si copia il float [i] nell'array di byte, dovresti scrivere qualcosa come

Array.Copy(BitConverter.GetBytes(float[i]),0,res,i*4); 

invece di:

ret = BitConverter.GetBytes(floats[i]); 

la funzione inversa seguire la stessa strategia.

+0

+1: Sì, sembra ok. Ho perso questa parte della domanda. – Ani

+0

hmm sembra che manchi un parametro ... – LamonteCristo

+0

l'ultimo parametro è 4 per Array.Copy. +1 Segnalo come risposta alla domanda (poiché affronta la domanda nel titolo), ma Ani ha dato così tanto tempo nella sua risposta. Solo una differenza di 5 punti comunque ... – LamonteCristo

Problemi correlati