2011-11-12 26 views
5

Estoy tratando de convertir 3 bytes en un entero con signo (Big-endian) en C#.Convertir 3 bytes en un entero con signo en C#

He intentado utilizar el método BitConverter.ToInt32, pero mi problema es qué valor debe tener el byte lats.

¿Alguien puede sugerirme cómo puedo hacerlo de otra manera?

También necesito convertir 5 (o 6 o 7) bytes a longitud firmada, ¿hay alguna regla general de cómo hacerlo?

Gracias de antemano por cualquier ayuda.

+1

¿Firma y Magnitud? Complemento de dos? – Ani

+0

Está en complemento de dos –

Respuesta

8

Como último recurso, siempre se puede cambiar + agregarse:

byte b1, b2, b3; 

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

Sólo b1 de intercambio/b2/b3 hasta que tengas el resultado deseado.

Pensándolo bien, esto nunca producirá valores negativos.
¿Qué resultado desea cuando el msb> = 0x80?


Parte 2, bruta fuerza de extensión de signo:

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; 
    } 

he probado esto con:

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

para varios p.

+0

bien, pero necesito valores negativos también –

+0

bien, gracias por su ayuda. Mi solución final es un poco diferente, pero también uso el mecanismo de verificación del bit más significativo (b1 y 0x80) para determinar si el número es positivo o negativo. –

+0

@ vc.one, sí, gracias por la edición. El '+' también necesitaba '()': '(b1 << 16) + ...' –

4

El último valor debe ser 0 si no está establecido para un número positivo, 256 para un negativo.

para saber lo que debe pasar en, puede intentar convertir a la inversa:

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

añadiendo 0 es incorrecto si el número que convierte tiene signo menos –

+0

@RafalSpacjer lo cambió –

0

Para añadir a las respuestas existentes aquí, hay un poco de Gotcha en que Bitconverter.ToInt32() lanzará un ArgumentException si la matriz es menor que sizseof(int) (4) bytes de tamaño;

La matriz de destino no es lo suficientemente larga para copiar todos los elementos de la colección. Verifique el índice y la longitud de la matriz.

Dada una matriz de menos de sizeof(int) (4) bytes de tamaño, puede compensar el relleno a la izquierda/derecha como tal;

derecho del cojín

Resultados en Int32 números positivos

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

Izquierda-pad

Resultados en Int32 números negativos, asumiendo valor distinto de cero en el índice 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 vez rellenada, se puede llamar de forma segura int myValue = BitConverter.ToInt32(sourceBytes, 0);.

Cuestiones relacionadas