2009-09-18 3 views
7

Ho bisogno di inserire coppie di byte e di produrre cortocircuiti, inserire cortocircuiti e emettere coppie di byte. Ecco le funzioni che ho escogitato per tale scopo:Un buon modo per convertire tra brevi e byte?

static short ToShort(short byte1, short byte2) 
{ 
    short number = (short)byte2; 
    number <<= 4; 
    number += (short)byte1; 
    return number; 
} 
static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte byte2 = (byte)(number >> 4); 
    short tempByte = (short)byte2 << 4; 
    byte byte1 = (byte)(number - tempByte); 
} 

Penso che sia corretto ma non ne sono sicuro. Se questo non è il modo giusto per farlo, che cos'è? c'è un modo per farlo già nel framework?

+0

È necessario spostare 8 bit, non 4. –

+0

Un cose interessanti qui è che in 'ToShort' il byte1 è l'MSB (cioè quello a sinistra), dove -come in' FromShort' il byte1 è l'LSB (cioè quello a destra). Ho cambiato questi nella mia risposta ;-p –

risposta

16

Shorter versione (spostando anche 8 bit invece di 4):

static short ToShort(short byte1, short byte2) 
{ 
    return (byte2 << 8) + byte1; 
} 

static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte2 = (byte)(number >> 8); 
    byte1 = (byte)(number & 255); 
} 
+0

penso che andrò con questo, grazie per l'aiuto! – RCIX

+4

ha dovuto avvolgere il codice nel metodo ToShort con un cast in short, ho pensato di farti sapere ... – RCIX

+0

questo non viene compilato ... perché così tanti upvotes? short + short si risolve in un operatore intero e non può cast implicitamente int come short – Assimilater

5

I byte sono 8 bit, non 4, quindi lo spostamento è disattivato. Hai anche dichiarato variabili locali nella seconda funzione in modo da non finire per scrivere i parametri out come vuoi. È anche più chiaro/migliore se si limita alle operazioni bit a bit (&, | e ~) laddove possibile.

static short ToShort(byte byte1, byte byte2) 
{ 
    return (short) ((byte2 << 8) | (byte1 << 0)); 
} 

static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte2 = (byte) (number >> 8); 
    byte1 = (byte) (number >> 0); 
} 

Si noti che i movimenti di sinistra e destra per zero non sono necessari, in senso stretto. Li ho messi per simmetria. Inoltre, personalmente ti consiglierei di imparare il freddo aritmetico bit a bit e saltare le funzioni di aiuto come queste. Non c'è bisogno di nascondere i dettagli con qualcosa di così fondamentale, IMHO.

+1

Questa è l'unica soluzione che consiglierei. – Goot

+1

Questa è l'unica soluzione corretta per il corto firmato – Yiping

+0

Questa dovrebbe essere la risposta accettata ... in realtà compila ... – Assimilater

4

Se si vuole prendere byte ... prendere byte; ei tuoi spostamenti sono spenti, e | sarebbero più intuitiva:

static short ToShort(byte byte1, byte byte2) 
{ // using Int32 because that is what all the operations return anyway... 
    return (short)((((int)byte1) << 8) | (int)byte2); 
} 
static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte1 = (byte)(number >> 8); // to treat as same byte 1 from above 
    byte2 = (byte)number; 
} 
+0

che prendere la cosa in byte era in realtà un errore ... Buoni consigli, grazie! – RCIX

+0

In genere si desidera spostare lo byte2, non il byte1. Quindi qualcosa come: return (short) ((byte2 << 8) | byte1); –

+0

sebbene i cast di int siano inutili mostra ciò che accadrà comunque (e penso che questo sia ciò che intendevi per il commento), quindi +1 – Assimilater

0

System.BitConverter

+1

Finché non ti occupi del sovraccarico di un array tutto il tempo, e non avendo il controllo sul fatto che si tratti di little-endian o big-endian .. –

+0

@Marc Gravell Per quanto riguarda il controllo, devi mettere in logica per gestire sia BE che LE, giusto? come invertire l'array giusto? Ma suppongo che la matrice sarebbe un leggero sovraccarico anche se ... – TJB

+1

Nel momento in cui hai messo questa logica, potresti anche aver appena usato l'aritmetica bit per bit ed evitato tutti i problemi ... se hai a che fare con le conversioni di byte, quindi imparare un po 'di matematica è probabilmente la migliore risposta; -p –

27

Usa BitConverter

short number = 42; 
byte[] numberBytes = BitConverter.GetBytes(number); 
short converted = BitConverter.ToInt16(numberBytes); 
+0

Hmm non ci ha pensato, ma per ora mi piace lo slogan di Ates. Grazie! – RCIX

+2

Qualunque cosa funzioni meglio per te! Il vantaggio di utilizzare un metodo come questo è che se devi usare questo codice in altri progetti sarà solo lì invece di dover creare una libreria e condividere il codice. Inoltre, altri sviluppatori possono riutilizzare la propria conoscenza di BitConverter se ne hanno. Personalmente, avevamo un codice wrapper per le conversioni di byte che avremmo condiviso, ma è diventato più di una seccatura mantenere piuttosto che usare solo le cose integrate. Ma seriamente, usa ciò che funziona meglio per te; – TJB

+1

Come programmatore ac/C++ a cuore trovo sciocco che chiunque lo troverebbe gravoso per fare un semplice bitshift o operazione ... generando un 'byte []' e poi comunque 'BitConverter' è implementato per analizzare detto byte [] 'dopo sembra solo sciocco .... – Assimilater