2011-08-23 14 views
8

Tengo una especificación que dice que los dos siguientes bytes están firmados int.cómo leer int firmado desde bytes en java?

leer que en Java Tengo el siguiente

Cuando leo un int firmado en Java usando el siguiente código me sale un valor de 65449

lógica para el cálculo de firmar

int a =(byte[1] & 0xff) <<8 

int b =(byte[0] & 0xff) <<0 

int c = a+b 

Creo que esto es incorrecto porque si yo y con 0xff obtengo un equivalente sin signo

entonces quité el & 0xff y la lógica como se indica a continuación

int a = byte[1] <<8 
int b = byte[0] << 0 
int c = a+b 
which gives me the value -343 
byte[1] =-1 
byte[0]=-87 

Traté de compensar estos valores con la forma en la especificación lee, pero esto se ve wrong.Since el tamaño del montón doesnt se incluyen en esta.

¿Cuál es la forma correcta de hacer el cálculo int firmado en java?

Así es como la especificación va

somespec() { xtype 8 uint8 xStyle 16 int16 } Xstyle: Un entero con signo que representa una estructura de compensación (en bytes) desde el inicio de este widget() para el inicio de una estructura Xstyle() que expresa heredado estilos para el widget definido por página, así como estilos que se aplican específicamente a este widget.

+0

¿Puede mostrar un ejemplo de entrada y el resultado deseado? no está claro ... – MByD

+0

leo esto de una secuencia usando una especificación. Leo los dos bytes según la especificación y los valores cuando leo en una matriz de bytes cuando se convierten a bytes individuales son byte [1] = - 1 y byte [0] = - 87 dicen en una matriz de bytes que contiene dos bytes. La especificación marca estos dos bytes como firmados int y no sé cuál es el resultado correcto. – Siva

Respuesta

13

Si el valor es un signo de 16 bits que quieren un short y int es de 32 bits, que también puede contener los mismos valores pero no de forma tan natural.

Parece que quiere un pequeño valor endian firmado de 16 bits.

byte[] bytes = 
short s = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort(); 

o

short s = (short) ((bytes[0] & 0xff) | (bytes[1] << 8)); 

Por cierto: se puede usar un int, pero no es tan simple.

// to get a sign extension. 
int i = ((bytes[0] & 0xff) | (bytes[1] << 8)) <<16>> 16; 

o

int i = (bytes[0] & 0xff) | (short) (bytes[1] << 8)); 
+0

esto funcionó. gracias – Siva

2

No puedo compilarlo en este momento, pero lo haría (suponiendo que byte1 y byte0 son realtings del tipo de byte).

int result = byte1; 
result = result << 8; 
result = result | byte0; //(binary OR) 
if (result & 0x8000 == 0x8000) { //sign extension 
    result = result | 0xFFFF0000; 
} 

si byte1 y byte0 son enteros, tendrá que hacer el `& 0xFF

actualización porque Java fuerza a la expresión de un caso de ser un valor lógico

+0

si hago esto, obtengo una desviación de -87, intentaré esto y veré si puedo leer el valor en el montón. También podría por favor ayudarme a verificar si esto debería leer esta especificación somespec() { xtype 8 uint8 xStyle 16 int16} xStyle: Un entero con signo que representa un desplazamiento (en bytes) desde el inicio de esta estructura Widget() al comienzo de una estructura xStyle() que expresa estilos heredados para el widget definido por página y estilos que se aplican específicamente a este widget. – Siva

2

echar un vistazo en DataInputStream.readInt(). Puede usar código de acero desde allí o simplemente usar DataInputStream: envuelva su flujo de entrada con él y luego lea los datos escritos fácilmente.

Para su comodidad este es el código:

public final int readInt() throws IOException { 
    int ch1 = in.read(); 
    int ch2 = in.read(); 
    int ch3 = in.read(); 
    int ch4 = in.read(); 
    if ((ch1 | ch2 | ch3 | ch4) < 0) 
     throw new EOFException(); 
    return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); 
} 
+1

Esto lee valores de 32 bitios de big-endian, creo que el OP quiere un pequeño valor endian de 16 bits. –

4

Suponiendo que los bytes [1] es el MSB y bytes [0] es el LSB, y que quiere que la respuesta sea un entero de 16 bits:

short res16 = ((bytes[1] << 8) | bytes[0]); 

a continuación, para obtener un entero de 32 bits:

int res32 = res16; // sign extends. 

Por cierto, la especificación debería decir cuál de los dos bytes es el MSB, y cuál es el LSB. Si no lo hace y si no hay ningún ejemplo, ¡no puede implementarlo!


En algún lugar de la especificación se indicará cómo se representa un "int16". Pega ESA parte. O pegue un enlace a la especificación para que podamos leerlo nosotros mismos.

+0

por favor vea mis ediciones en la consulta principal, he dado cómo lee la especificación – Siva

1

¿tiene alguna forma de encontrar una salida correcta para una entrada determinada? técnicamente, un tamaño int es de 4 bytes, por lo que con solo 2 bytes no puede alcanzar el bit de signo.

+0

somespec() { xtype 8 uint8 pwStyle 16 int16} Un entero con signo que representa un desplazamiento (en bytes) desde el inicio de este Widget () estructura al comienzo de una estructura xStyle() que expresa estilos heredados para widget de página definido como , así como estilos que se aplican específicamente a este widget. – Siva