2009-09-18 7 views
7

Necesito tomar pares de bytes y salir cortos, y tomar cortos y salir pares de bytes. Estas son las funciones que he ideado para tal fin:¿Una buena forma de convertir entre short y bytes?

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

Creo que esto es correcto, pero no estoy seguro. Si esta no es la forma correcta de hacerlo, ¿qué es? ¿Hay alguna forma de hacerlo en el marco?

+0

Es necesario cambiar de 8 bits, no –

+0

4. Un cosas interesantes aquí es que en 'ToShort' byte1 es el MSB (es decir, el de la izquierda), donde-como en' FromShort' byte1 es el LSB (es decir, el de la derecha). He cambiado esto en mi respuesta ;-p –

Respuesta

16

Shorter versión (también cambiando 8 bits en lugar de 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

Creo que voy a ir con esto, gracias por la ayuda! – RCIX

+4

tenía que ajustar el código en el método ToShort con un lanzamiento corto, solo pensé que le haría saber ... – RCIX

+0

esto no compila ... ¿por qué tantos votos hacia arriba? short + short se resuelve en un operador entero y no puede convertir imp int como short – Assimilater

5

Los bytes son 8 bits, no 4, por lo que su desplazamiento está desactivado. También declaró variables locales en la segunda función para que no termine escribiendo los parámetros out como pretende. También es más claro/mejor si se limita a operaciones bit a bit (&, | y ~) siempre que sea posible.

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

Tenga en cuenta que los cambios hacia la izquierda y la derecha en cero son innecesarios, en sentido estricto. Acabo de ponerlos por simetría. Además, personalmente, te recomiendo que aprendas aritmética bit a bit y omitas las funciones de escritura de ayudantes como estas. No es necesario ocultar los detalles con algo tan fundamental, en mi humilde opinión.

+1

Esta es la única solución que recomendaría. – Goot

+1

Esta es la única solución que es correcta para short firmado – Yiping

+0

Esta debería ser la respuesta aceptada ... en realidad compila ... – Assimilater

4

Si usted quiere tomar bytes ... tomar bytes; y sus cambios están apagados, y | serían más 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

que tomar bytes es en realidad un error ... ¡Buenos consejos, gracias! – RCIX

+0

Por lo general, querrá cambiar bit byte2, no byte1. Entonces algo así como: return (short) ((byte2 << 8) | byte1); –

+0

aunque los int cast son innecesarios, muestra lo que ocurrirá de todos modos (y creo que esto es lo que querías decir con el comentario), así que +1 – Assimilater

0

System.BitConverter

+1

siempre y cuando no te importe la sobrecarga de una matriz todo el tiempo, y no teniendo control sobre si se trata de little-endian o big-endian .. –

+0

@Marc Gravell En cuanto a tener el control, tendrás que poner la lógica para manejar BE y LE ¿verdad? lo mismo que invertir la matriz ¿verdad? Pero supongo que el conjunto sería un ligero sobrecarga ... – TJB

+1

Para cuando hayas puesto esa lógica, bien podrías haber usado la aritmética bit a bit y haber evitado todos los problemas ... si estás tratando con conversiones de bytes, entonces aprender un poco de matemática es probablemente la mejor respuesta; -p –

27

Uso BitConverter

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

Hmm no pensó en esto, pero me gusta la situación de Ates por ahora. ¡Gracias! – RCIX

+2

¡Lo que sea mejor para usted! La ventaja de utilizar un método como este es que si tiene que usar este código en otros proyectos, estará allí en lugar de tener que crear una biblioteca y compartir el código. Además, otros desarrolladores pueden volver a utilizar sus conocimientos de BitConverter si tienen alguno. Personalmente, solíamos tener algún código de envoltura para las conversiones de bytes que compartíamos, pero se volvió más complicado de mantener en lugar de usar las cosas integradas. Pero en serio, usa lo que funcione mejor para ti;) – TJB

+1

Como programador de ac/C++ en mi corazón, me parece una tontería que a alguien le resulte oneroso hacer un simple cambio de bits y/u operación ... generando un 'byte []' y luego sin embargo 'BitConverter' se implementa para analizar dicho' byte [] 'luego parece tonto ... – Assimilater

Cuestiones relacionadas