2011-11-12 17 views
5

Sto provando a convertire 3 byte in intero con segno (Big-endian) in C#.Conversione di 3 byte in numero intero con segno in C#

Ho provato a utilizzare il metodo BitConverter.ToInt32, ma il mio problema è quale valore dovrebbe avere il byte lats.

Qualcuno può suggerirmi come posso farlo in modo diverso?

Ho anche bisogno di convertire 5 (o 6 o 7) byte per firmare a lungo, c'è qualche regola generale come farlo?

Grazie in anticipo per qualsiasi aiuto.

+1

Segno e grandezza? Complemento di due? – Ani

+0

È in complemento a due –

risposta

8

Come ultima risorsa si può sempre spostare + aggiungere se stessi:

byte b1, b2, b3; 

int r = b1 << 16 | b2 << 8 | b3; 

Proprio di swap b1/b2/b3 finché non si ottiene il risultato desiderato.

Ripensandoci, questo non produrrà mai valori negativi.
Quale risultato si desidera quando msb> = 0x80?


Parte 2, Brute Force segno estensione:

private static int Bytes2Int(byte b1, byte b2, byte b3) 
    { 
     int r = 0; 
     byte b0 = 0xff; 

     if ((b1 & 0x80) != 0) r |= b0 << 24; 
     r |= b1 << 16; 
     r |= b2 << 8; 
     r |= b3; 
     return r; 
    } 

Ho provato questo con:

 byte[] bytes = BitConverter.GetBytes(p); 
     int r = Bytes2Int(bytes[2], bytes[1], bytes[0]); 
     Console.WriteLine("{0} == {1}", p, r); 

per diversi p.

+0

ok, ma ho bisogno di valori negativi anche –

+0

ok, grazie per l'aiuto. La mia soluzione finale è leggermente diversa, ma uso anche il meccanismo di controllo del bit più significativo (b1 e 0x80) per determinare se il numero è positivo o negativo. –

+0

@ vc.one, sì, grazie per la modifica. Il '+' aveva anche bisogno di '()': '(b1 << 16) + ...' –

4

L'ultimo valore deve essere 0 se non è impostato per un numero positivo, 256 per un negativo.

di sapere che cosa si dovrebbe passare, si può provare a convertire il contrario:

var bytes = BitConverter.GetBytes(i); 
int x = BitConverter.ToInt32(bytes, 0); 
+0

l'aggiunta 0 è errata se il numero di conversione ha il segno meno –

+0

@RafalSpacjer lo ha modificato –

0

da aggiungere alle risposte esistenti qui, c'è un po 'di Gotcha in quel Bitconverter.ToInt32() getterà un ArgumentException se la matrice è inferiore a sizseof(int) (4) byte di dimensione;

L'array di destinazione non è sufficiente per copiare tutti gli elementi nella raccolta. Controlla l'indice e la lunghezza dell'array.

Dato un array inferiore a sizeof(int) (4) byte di dimensioni, è possibile compensare il riempimento sinistro/destro in questo modo;

destro del pad

Risultati in positivi Int32 numeri

int intByteSize = sizeof(int); 
byte[] padded = new byte[intByteSize]; 
Array.Copy(sourceBytes, 0, padded, 0, sourceBytes.Length); 
sourceBytes = padded; 

Sx-pad

Risultati in negativo Int32 numeri, assumendo valore diverso da zero di indice byte sourceBytes.Length - 1.

int intByteSize = sizeof(int); 
byte[] padded = new byte[intByteSize]; 
Array.Copy(sourceBytes, 0, padded, intByteSize - sourceBytes.Length, sourceBytes.Length); 
sourceBytes = padded; 

Una volta riempita, si può tranquillamente chiamare int myValue = BitConverter.ToInt32(sourceBytes, 0);.

Problemi correlati