Autore Topic: Bit più significativo  (Letto 879 volte)

Offline davix10

  • Utente normale
  • ***
  • Post: 159
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Lg G4
  • Play Store ID:
    davix10
  • Sistema operativo:
    Windows 10
Bit più significativo
« il: 24 Ottobre 2014, 23:10:11 CEST »
0
Salve a tutti, io ricevo 2 byte per volta da uno strumento ma ho bisogno di controllare il bit più significativo per sapere se il valore che ricevo è negativo o positivo. In questo momento utilizzo questa funzione:

Codice (Java): [Seleziona]
byte[] readBuf = (byte[]) msg.obj;
int valore_a_16   = ((readBuf[1] & 0xFF) << 8) | (readBuf[0] & 0xFF);

Come posso modificare il codice per ottenere il valore del bit più significativo?
Grazie in anticipo

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Bit più significativo
« Risposta #1 il: 25 Ottobre 2014, 01:16:45 CEST »
0
Basta fare un cast con uno short (bit 16) e fai il test se è negativo, se ho capito la domanda, il codice che hai riportato esegue un cast con un intero (32 bit) e il bit di segno non è al sedicesimo bit.

Inviato dal mio Nexus 5 utilizzando Tapatalk

adb logcat | tee /tmp/logcat | grep TAG

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #2 il: 27 Ottobre 2014, 10:27:42 CET »
+1
Il bit più significativo dei tuoi 16?

Codice (Java): [Seleziona]
    boolean bit = ((valore_a_16 & 0x8000) == 0x8000);
Ciao.

P.S. Ho visto anche la risposta di Iceweasel. E' ovviamente corretta, ma credo che pecchi in leggibilità.

P.P.S. Ho riletto la domanda... Ho visto che il tuo obiettivo era proprio capire il segno del valore... direi che allora che la risposta di Iceweasel non pecca il leggiblità. Sorry, avevo letto la domanda a metà.
« Ultima modifica: 27 Ottobre 2014, 14:34:28 CET da arlabs »

Offline davix10

  • Utente normale
  • ***
  • Post: 159
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Lg G4
  • Play Store ID:
    davix10
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #3 il: 27 Ottobre 2014, 12:56:16 CET »
0
Grazie mille per le risposte! Ma se io usassi un altro tipo di variabile potrei capire, senza utilizzare alcuna funzione, se i 16 bit corrispondono ad un valore positivo o negativo?

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #4 il: 27 Ottobre 2014, 14:44:55 CET »
0
Come diceva Iceweasel:

Codice (Java): [Seleziona]
        short valore_a_16   = (short)((readBuf[1] << 8) | readBuf[0]);
        if( valore_a_16 < 0 )
       {

       }

Ciao.

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Bit più significativo
« Risposta #5 il: 27 Ottobre 2014, 14:50:18 CET »
0
arlabs e iceweasel hanno ragione ma non è detto che la soluzione sia "a prova di bomba".

Bisogna essere sicuri che non ci siano differenze di endianness tra i device.

Endianness - Wikipedia, the free encyclopedia

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #6 il: 27 Ottobre 2014, 14:56:57 CET »
0
Potrebbe essere ancor più semplice castare direttamente il tuo msg.obj a short, ma non conosco dettagli di Endianness in Java...

Sicuramente Iceweasel può risponderti meglio.

P.S. Ecco, appunto undead ha detto bene... devi anche essere sicuro dell'endianness della sorgente dei dati che ti arrivano.

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Bit più significativo
« Risposta #7 il: 27 Ottobre 2014, 15:32:01 CET »
0
Da quanto ne so a livello teorico le comunicazioni di rete sono big endian e sempre a livello teorico anche java è big endian.

Poi nello specifico se si usa un nio buffer bisogna verificare l'endianness della piattaforma con:

ByteOrder | Android Developers

Per quanto riguarda il "sender" bisogna vedere che strumento è.  :-)

Offline davix10

  • Utente normale
  • ***
  • Post: 159
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Lg G4
  • Play Store ID:
    davix10
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #8 il: 27 Ottobre 2014, 15:58:12 CET »
0
Ho provato ad usare questo metodo:
Codice (Java): [Seleziona]
 short valore_a_16   = (short)((readBuf[1] << 8) | readBuf[0]);
ma ricevo dei valori diversi da quelli che dovrei ricevere.
Sembra che una buona parte la ricevo giusta ma ogni tanto ottengo dei valori completamente diversi

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Bit più significativo
« Risposta #9 il: 27 Ottobre 2014, 17:27:52 CET »
+1
L'ordine dei byte è indicato di solito con i termini big-endian e little-endian, dipende dalla CPU in uso e deve essere conosciuto a priori, non può essere indeterminato.

Nel protocollo TCP/IP si usa il big-endian perché i computer utilizzati per programmare la prima implementazione usavano CPU con quel ordine di byte.

Le CPU Intel architettura x86 utilizzano little-endian.

Le CPU ARM possono essere configurate al boot per utilizzare big-endian o little-endian, sotto Android sono configurate di solito little-endian.

Android può girare sia con CPU big-endian che little-endian. Nelle API è presente un metodo per sapere l'ordine dei byte in uso:

http://developer.android.com/reference/java/nio/ByteOrder.html

Inviato dal mio Nexus 5 utilizzando Tapatalk
« Ultima modifica: 27 Ottobre 2014, 20:14:20 CET da iceweasel »
adb logcat | tee /tmp/logcat | grep TAG

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #10 il: 28 Ottobre 2014, 09:30:30 CET »
0
Ho provato ad usare questo metodo:
Codice (Java): [Seleziona]
 short valore_a_16   = (short)((readBuf[1] << 8) | readBuf[0]);
ma ricevo dei valori diversi da quelli che dovrei ricevere.
Sembra che una buona parte la ricevo giusta ma ogni tanto ottengo dei valori completamente diversi

Sì, infatti quel codice è sbagliato :)

readBuf[0] è byte (signed), viene convertito in intero e se il primo bit è 1, il valore viene interpretato negativo e il primo bit (1) viene propagato nei bit più significativi. In OR con readBuf[1] << 8 chiaramente fa casino.

Questo dovrebbe essere giusto.

Codice (Java): [Seleziona]
    short valore_a_16   = (short)((readBuf[1] << 8) | (readBuf[0] & 0xFF));
Ciao.

Offline davix10

  • Utente normale
  • ***
  • Post: 159
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Lg G4
  • Play Store ID:
    davix10
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #11 il: 28 Ottobre 2014, 12:04:26 CET »
0
Ho scoperto che il mio strumento utilizza il little-endian. Non capisco però perchè si perde dei dati, ne dovrei ricevere 1000 al secondo e ne ricevo circa 500. Quale può essere il motivo?

Offline davix10

  • Utente normale
  • ***
  • Post: 159
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Lg G4
  • Play Store ID:
    davix10
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #12 il: 31 Ottobre 2014, 23:43:29 CET »
0
Nessuno può aiutarmi?

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #13 il: 01 Novembre 2014, 09:33:56 CET »
0
Innanzitutto verifica se, quando, come li perdi.

Ti consiglio di spedire una serie consecutiva di numeri da un lato e riceverli e verificarli dall'altra.

Se sono tutti valori sbagliati potrebbe essere che impacchetti e spacchetti in modo non coerente (spedisci 8 bit e ne estrai 16?)
Se ne perdi un burst ogni tanto potrebbe essere che gestisce in modo errato read e write.

Non è che ti si possa essere molto utile con le poche informazioni che hai scritto...

Ciao.

Offline davix10

  • Utente normale
  • ***
  • Post: 159
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Lg G4
  • Play Store ID:
    davix10
  • Sistema operativo:
    Windows 10
Re:Bit più significativo
« Risposta #14 il: 01 Novembre 2014, 11:59:04 CET »
0
Ho provato a cambiare le impostazioni del mio strumento per rendere le cose più facili: ora invio un byte ogni millisecondo e lo leggo in questo modo:

Codice (Java): [Seleziona]
 byte new1= readBuf[0];
i dati che leggo sono gli stessi che dovrei ricevere ma il problema è che non li ricevo tutti.