2011-08-23 11 views
8

Ho una specifica che legge i prossimi due byte sono firmati int.come leggere l'int firmato da byte in java?

leggere che in Java ho le seguenti

Quando leggo un int firmato in Java utilizzando il seguente codice ottengo un valore di 65449

logica per il calcolo di unsigned

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

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

int c = a+b 

Credo che questo sia sbagliato perché se io e con 0xff ottengo un equivalente senza segno

così ho rimosso il & 0xff e la logica, come riportato qui di seguito

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 

ho cercato di compensare questi valori con il modo in cui le specifiche legge, ma questo sembra wrong.Since la dimensione del mucchio doesnt rientrano in questa.

Qual è il modo giusto di fare per il calcolo int firmato in java?

Ecco come le specifiche va

somespec() { xtype 8 uint8 xStyle 16 int16 } Xstyle: Un intero con segno che rappresenta una struttura di offset (in byte) dall'inizio di questo Widget() per l'inizio di una struttura Xstyle() che esprime ereditato stili definiti per widget di pagina e stili che si applicano specificamente a questo widget.

+0

Puoi mostrare un esempio di input e il risultato desiderato? non è chiaro .. – MByD

+0

ho letto questo da uno stream utilizzando una specifica. Ho letto i due byte come da specifica e i valori letti in un array di byte quando convertiti in singoli byte sono byte [1] = - 1 e byte [0] = - 87 dicono in un array di byte contenente due byte. La specifica contrassegna questi due byte come firmati int e non so quale sia l'output corretto. – Siva

risposta

13

Se il valore è un segno a 16 bit che si desidera un short e int è a 32 bit che può anche contenere gli stessi valori, ma non in modo così naturale.

Sembra che si desidera un valore di 16 bit bit little endian firmato.

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

o

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

BTW: È possibile utilizzare un int, ma la sua non è così semplice.

// 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

ha funzionato. grazie – Siva

2

Al momento non riesco a compilarlo, ma lo farei (supponendo che byte1 e byte0 realizzino il tipo di byte).

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

se byte1 e byte0 sono interi, sarà necessario fare il `& 0xFF

UPDATE perché Java costringe l'espressione di un caso di essere un valore booleano

+0

se faccio questo ottengo un offset di -87, proverò questo e vedrò se sono in grado di leggere il valore nell'heap.Inoltre potresti aiutarmi a verificare se questo come dovrei leggere questa spec somespec() {) { xtype 8 uint8 xStyle 16 int16} xStyle: un intero con segno che rappresenta un offset (in byte) dall'inizio di questa struttura Widget() all'inizio di una struttura xStyle() che esprime stili ereditati per definiti dal widget di pagina e stili che si applicano specificamente a questo widget. – Siva

2

dare uno sguardo su DataInputStream.readInt(). Puoi utilizzare il codice di acciaio o utilizzare semplicemente DataInputStream: avvolgere il flusso di input con esso e quindi leggere facilmente i dati digitati.

Per comodità Questo è il codice:

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

Questo legge valori big-endian a 32 bit, credo che l'OP voglia un valore little endian a 16 bit. –

4

Supponendo che i byte [1] è il MSB, e byte [0] è il LSB, e che si vuole la risposta ad essere un numero intero con segno a 16 bit:

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

Poi per ottenere un numero intero con segno a 32 bit:

int res32 = res16; // sign extends. 

A proposito, la specifica dovrebbe indicare quale dei due byte è l'MSB e quale è l'LSB. Se non lo fa e se non ci sono esempi, non puoi implementarlo!


Da qualche parte nelle specifiche dirà come viene rappresentato un "int16". Incolla QUELLA parte. Oppure incollare un collegamento alle specifiche in modo che possiamo leggerlo da soli.

+0

si prega di vedere le mie modifiche nella query principale, ho dato come la spec legge – Siva

1

hai un modo di trovare un output corretto per un dato input? tecnicamente, una dimensione int è di 4 byte, quindi con solo 2 byte non è possibile raggiungere il bit di segno.

+0

somespec() { xtype 8 uint8 pwStyle 16 int16} Un intero con segno che rappresenta un offset (in byte) dall'inizio di questo Widget () struttura all'inizio di una struttura xStyle() che esprime stili ereditati per definiti dal widget di pagina come nonché stili che si applicano specificamente a questo widget. – Siva