2012-10-31 15 views
8
  1. Voglio convertire i byte in int in Java. Voglio assumere byte per essere senza segno. Supponiamo che seconvertire 3 byte in int in java

    byte a = (byte)0xFF; 
    
    int r = (some operation on byte a); 
    

    r dovrebbe essere 255 non -1 in decimale.

  2. Quindi voglio creare un valore int da 3 byte. Supponiamo che se

    byte b1 = (byte)0x0F; 
    
    byte b2 = (byte)0xFF; 
    
    byte b3 = (byte)0xFF; 
    
    int r = (some operation in bytes b1, b2 and b3); 
    

    Poi r dovrebbe essere 0x000FFFFF. Il byte b1 sarà posizionato nella terza posizione più alta e il byte b3 sarà collocato nella prima posizione inferiore in valore int. Anche il mio b1 andrà da 0x00 a 0x0F e altri byte saranno da 0x00 a 0xFF, assumendo la natura non firmata dei byte. Se il byte b1 è maggiore di 0x0F, estrarrò solo i 4 bit più bassi. In breve voglio estrarre int da 3 byte ma usando solo 20 bit di 3 byte. (totale 16 bit da b2 e b3 e 4 bit più bassi da b1). int r deve essere positivo dato che stiamo creando da 3 byte e assumendo la natura non firmata dei byte.

risposta

3

bisogna essere cauti con l'estensione del segno qui - purtroppo, i byte vengono firmati in Java (per quanto ne so, questo ha causato altro che dolore).

Quindi devi fare un po 'di mascheramento.

int r = (b3 & 0xFF) | ((b2 & 0xFF) << 8) | ((b1 & 0x0F) << 16); 
+0

Grazie mille, sto ottenendo la risposta giusta con la tua soluzione. Per favore, puoi spiegare perché il reverse order, intendo partire da b1 in sopra, mi dà 32640, ecco quale soluzione pubblicata da @ppeterka. – UDPLover

+0

@ user1508907 beh, l'ordine non dovrebbe avere importanza, ma la risposta di ppeterka potrebbe avere un problema con l'associazione '+' più fortemente di '<<'. – harold

+0

Sì, ho capito. ppeteka non sta usando la parentesi. E la soluzione è stata incasinata a causa delle regole di precedenza degli operatori – UDPLover

1

Ecco una versione "sposta solo":

int r = ((b1 << 28) >>> 12) | (b2 << 8) | b3; 

Spostamento sinistra 28 bit costolette di fuori i primi 4 bit, quindi spostando a destra 12 lo riporta un netto spostamento a sinistra 16 bit.

ho provato questo codice e funziona :)

+0

si può spiegare ciò che vi aspettate di ottenere con spostamento eccessivo? –

+0

Wow, spostando di 36 bit per tagliare i primi 4 bit :) Eeeeevil :) Mi piace! È un piacere imparare qualcosa ogni giorno! – ppeterka

+0

Questo firmerà estendere il 20 ° bit. Se non vuoi che tu possa usare '>>>' –

2

Questo è abbastanza facile con gli operatori bitshifting e AND binario. Si desidera utilizzare solo i 4 bit inferiori di b1, questo è esattamente ciò che fa b1 & 0x0F. Tutto il resto si sta spostando i bit di varie posizioni

int r = ((b1 & 0x0F) << 16) + ((b2 & 0xFF) << 8) + (b3 & 0xFF) 

EDIT come @harold sottolineato, la prima soluzione (senza la maschera 0xFF sui byte inferiori) avrebbe portato ad anomalie causate firmare estensione .. .

EDIT2 accidenti, ho sempre arrivare un pugno in faccia da parte dell'operatore la precedenza quando si tratta di questi ...

letture consigliate:

+0

Crap, molto vero! Aggiornerà subito. – ppeterka

+0

Ho provato superiore alla public class principale { public static void main (String [ ] args) { byte b1 = (byte) 0x0f; byte b2 = (byte) 0xFF; byte b3 = (byte) 0xFF; int r = (b1 e 0x0F << 16) + (b2 & 0xFF) << 8 + (b3 & 0xFF); // stampa - r: 32640 // Voglio r: 1048575 System.out.println ("r:" + r); }} sua dandomi 32640, voglio 1048575 – UDPLover

+0

Grazie, ma la soluzione è sbagliato. Quando parto da b3 anziché da b1, mi dà la risposta giusta, come da harold. Utilizzando la soluzione sua darmi 32640, voglio 1048575. – UDPLover

3

Vorrei assumere desideri byte senza segno valori

int r = ((b1 & 0xF) << 16) | ((b2 & 0xFF) << 8) | (b3 & 0xFF); 

Ogni byte ha bisogno di essere mascherato e spostato verso il Bit destro.

+1

Questa è la soluzione giusta. Grazie – UDPLover

0

Ho confrontato alcune risposte, dato che ero curioso quale fosse il più veloce.

Sembra come il metodo di Boemia è il più veloce, ma non riesco a spiegare il motivo per cui è l'11% più lento nella prima manche.

PS: Non ho controllato le risposte per correttezza.

Ecco il codice:

public class Test 
{ 

    public static void main(String[] args) 
    { 
    final int RUNS = 10; 
    final int TRIPLE = 3; 
    final int N = 100000000; 

    byte[] bytes = new byte[TRIPLE * 32768]; // 96 kB 

    Random r = new Random(); 
    r.nextBytes(bytes); 

    List<ByteConvertTester> testers = Arrays.asList(new Harold(), new Bohemian(), new Ppeterka()); 

    for (int i = 0; i < RUNS; i++) 
    { 
     System.out.println("RUN#" + i); 
     System.out.println("----------------------"); 
     Integer compare = null; 
     for (ByteConvertTester tester : testers) 
     { 
     System.out.println(tester.getClass().getSimpleName()); 
     long time = testAndMeasure(tester, bytes, N); 
     System.out.print("time (in ms): " + time); 
     if (compare != null) { 
      System.out.println(" SpeedUp%: " + (double) ((int) (10000 * (1.0d - (double) time/compare)))/100); 
     } else { 
      compare = (int) time; 
      System.out.println(); 
     } 
     } 
     System.out.println("----------------------"); 
    } 
    } 

    private static long testAndMeasure(ByteConvertTester bct, byte[] bytes, int loops) 
    { 
    Calendar start = Calendar.getInstance(); 
    int r; 
    for (int i = 0; i < loops; i += 3) 
     r = bct.test(bytes[i % bytes.length], bytes[(i + 1) % bytes.length], bytes[(i + 2) % bytes.length]); 

    Calendar end = Calendar.getInstance(); 
    long time = (end.getTimeInMillis() - start.getTimeInMillis()); 
    return time; 
    } 
} 

interface ByteConvertTester 
{ 
    public int test(byte msb, byte mid, byte lsb); 
} 

class Harold implements ByteConvertTester 
{ 
    @Override 
    public int test(byte msb, byte mid, byte lsb) 
    { 
    return (lsb & 0xFF) | ((mid & 0xFF) << 8) | ((msb & 0x0F) << 16); 
    } 
} 

class Bohemian implements ByteConvertTester 
{ 
    @Override 
    public int test(byte msb, byte mid, byte lsb) 
    { 
    return ((msb << 28) >>> 12) | (mid << 8) | lsb; 
    } 
} 

class Ppeterka implements ByteConvertTester 
{ 

    @Override 
    public int test(byte msb, byte mid, byte lsb) 
    { 
    return ((msb & 0x0F) << 16) + ((mid & 0xFF) << 8) + (lsb & 0xFF); 
    } 
} 

USCITA

RUN#0 
---------------------- 
Harold 
time (in ms): 489 
Bohemian 
time (in ms): 547 SpeedUp%: -11.86 
Ppeterka 
time (in ms): 479 SpeedUp%: 2.04 
---------------------- 
RUN#1 
---------------------- 
Harold 
time (in ms): 531 
Bohemian 
time (in ms): 521 SpeedUp%: 1.88 
Ppeterka 
time (in ms): 537 SpeedUp%: -1.12 
---------------------- 
RUN#2 
---------------------- 
Harold 
time (in ms): 531 
Bohemian 
time (in ms): 539 SpeedUp%: -1.5 
Ppeterka 
time (in ms): 532 SpeedUp%: -0.18 
---------------------- 
RUN#3 
---------------------- 
Harold 
time (in ms): 529 
Bohemian 
time (in ms): 519 SpeedUp%: 1.89 
Ppeterka 
time (in ms): 531 SpeedUp%: -0.37 
---------------------- 
RUN#4 
---------------------- 
Harold 
time (in ms): 527 
Bohemian 
time (in ms): 519 SpeedUp%: 1.51 
Ppeterka 
time (in ms): 530 SpeedUp%: -0.56 
---------------------- 
RUN#5 
---------------------- 
Harold 
time (in ms): 528 
Bohemian 
time (in ms): 519 SpeedUp%: 1.7 
Ppeterka 
time (in ms): 532 SpeedUp%: -0.75 
---------------------- 
RUN#6 
---------------------- 
Harold 
time (in ms): 529 
Bohemian 
time (in ms): 520 SpeedUp%: 1.7 
Ppeterka 
time (in ms): 532 SpeedUp%: -0.56 
---------------------- 
RUN#7 
---------------------- 
Harold 
time (in ms): 529 
Bohemian 
time (in ms): 520 SpeedUp%: 1.7 
Ppeterka 
time (in ms): 533 SpeedUp%: -0.75 
---------------------- 
RUN#8 
---------------------- 
Harold 
time (in ms): 530 
Bohemian 
time (in ms): 521 SpeedUp%: 1.69 
Ppeterka 
time (in ms): 532 SpeedUp%: -0.37 
---------------------- 
RUN#9 
---------------------- 
Harold 
time (in ms): 529 
Bohemian 
time (in ms): 527 SpeedUp%: 0.37 
Ppeterka 
time (in ms): 530 SpeedUp%: -0.18 
----------------------