2010-04-17 13 views
10

Ho un controllo che contiene un array di byte.Converti 2 byte in un numero

Ogni tanto ci sono due byte che mi dicono alcune informazioni sul numero di articoli futuri nell'array.

Così, ad esempio avrei potuto:

 
... 
... 
Item [4] = 7 
Item [5] = 0 
... 
...

Il valore di questo è chiaramente 7.

Ma che dire di questo?

 
... 
... 
Item [4] = 0 
Item [5] = 7 
... 
...

Qualche idea su cosa equivale a (come un normale int)?

Sono andato al file binario e ho pensato che potesse essere 11100000000 che equivale a 1792. Ma non so se questo è il modo in cui funziona davvero (cioè utilizza tutti gli 8 elementi per il byte).

C'è un modo per sapere questo senza test?

Nota: io sto usando C# 3.0 e Visual Studio 2008

+4

Sembra che ci stiate chiedendo di eseguire il reverse-engineer di alcuni dati serializzati. Sarà difficile. Potresti almeno pubblicare alcuni esempi dell'intero array di byte e ciò a cui corrisponde per tre o quattro semplici esempi. Ma perché lo vuoi sapere comunque? Che problema stai cercando di risolvere? –

+0

Sto cercando di decifrare l'array di byte restituito dal controllo Signature nel controllo OpenNETCF in modo che possa ruotarlo di 180 gradi. Vedi questa domanda http://stackoverflow.com/questions/2657388/opennetcf-signature-control-question per maggiori dettagli. – Vaccano

risposta

19

BitConverter può convertire facilmente i due byte in un valore intero a due byte:

// assumes byte[] Item = someObject.GetBytes(): 
short num = BitConverter.ToInt16(Item, 4); // makes a short 
    // out of Item[4] and Item[5] 
+1

@Macho Matt: se vuoi commentare una risposta già accettata, è meglio lasciare un commento che modificare la domanda in sé. Inoltre, il tuo punto non era strettamente accurato - non importa se il sistema informatico è big-endian o little-endian, importa solo se il sistema che ha originariamente creato l'array di byte ha un endianness diverso rispetto al sistema eseguendo il codice .NET qui – MusiGenesis

+0

Ciò presuppone che l'MSB della rappresentazione binaria di questi due byte sia il bit di segno (1 = -ve, 0 = + ve). Se ciò non è il caso, cioè se il numero non è firmato , quindi è necessario utilizzare questo. ushort num = BitConverter.ToUInt16 (Item, 4). Inoltre, tenere presente che questo avrà byte nell'indice 5 come primo byte (byte più significativo) se la propria architettura è little endian. .azurewebsites.net/TwosComplementTut.aspx per mo re informazioni sul bit di segno. –

11

Un certo numero di due byte ha un basso e un byte alto. Il byte alto vale 256 volte tanto quanto il byte basso:

value = 256 * high + low; 

Così, per alta = 0 e bassa = 7, il valore è 7. Ma per alta = 7 e bassa = 0, il valore diventa 1792.

Questo ovviamente presuppone che il numero sia un numero intero a 16 bit semplice. Se è tutto più elaborato, quanto sopra non sarà sufficiente. Quindi è necessaria una maggiore conoscenza su come il codice è codificato, al fine di decodificarlo.

L'ordine di visualizzazione dei byte alto e basso è determinato dallo endianness del flusso di byte. In big-endian, vedrai alto prima del basso (a un indirizzo inferiore), in little-endian è il contrario.

+9

Vale anche la pena notare: '(alto << 8) | basso' – GeReV

0

Se quei byte sono le "parti" di un intero, funziona in questo modo. Ma attenzione, l'ordine dei byte è specifico della piattaforma e dipende anche dalla lunghezza del numero intero (16 bit = 2 byte, 32 bit = 4bytes, ...)

0

Usa BitConveter.ToInt32 im non 100% certo che ti darebbe il risultato giusto ma potresti provare

7

Tu dici "questo valore è chiaramente 7", ma dipende interamente dalla codifica. Se assumiamo byte a larghezza intera, in little-endian, sì; 7, 0 è 7. Ma in big endian non lo è.

Per little-endian, quello che vuoi è

int i = byte[i] | (byte[i+1] << 8); 

e per big-endian:

int i = (byte[i] << 8) | byte[i+1]; 

Ma altri schemi di codifica sono disponibili; per esempio, alcuni schemi usano l'aritmetica a 7 bit, con l'ottavo bit come un bit di continuazione. Alcuni schemi (UTF-8) inseriscono tutti i bit di continuazione nel primo byte (quindi il primo ha solo spazio limitato per i bit di dati) e 8 bit per il resto nella sequenza.

+0

Buon punto. Ma dall'uso posso vedere che il valore è 7 (ci sono altre sette sezioni di coordinate nell'array. – Vaccano

2

Se si vuole semplicemente mettere quelle due byte l'uno accanto all'altro in formato binario, e vedere che cosa quel grande numero è in decimale, allora avete bisogno di utilizzare questo codice:

  if (BitConverter.IsLittleEndian) 
      { 
       byte[] tempByteArray = new byte[2] { Item[5], Item[4] }; 
       ushort num = BitConverter.ToUInt16(tempByteArray, 0); 
      } 
      else 
      { 
       ushort num = BitConverter.ToUInt16(Item, 4); 
      } 

Se si utilizza short num = BitConverter.ToInt16(Item, 4); come si vede nella risposta accettata, si stanno assumendo che il primo bit di questi due byte è il bit del segno (1 = negativo e 0 = positivo). Questa risposta presuppone anche che tu stia usando un sistema big endian. Vedi this per maggiori informazioni sul bit di segno.

0

In caso quell'articolo [5] è il MSB

  1. risultato ushort = BitConverter.ToUInt16 (new byte [2] {articolo [5], punto [4]}, 0);

  2. int result = 256 * Articolo [5] + Articolo [4];