Domanda

Sto scrivendo una funzione brevi getbits (dati short, int p, int n)

ho provato:

public static short getBits(short data, int p, int n) {
    short bitmask = (short) ((~0 << (16 -n)) >>> p);
    short returnVal = (short) ((bitmask & data) >>> (16 - n));
    return returnVal;
}

Questo funziona per getbits ((brevi) 0x7000, 0, 4) ma se dovessi sostituire il 7 con 8 ottengo un valore negativo.

È stato utile?

Soluzione

Ci sono alcune cose da ricordare sui tipi di dati Java, per fare questo lavoro cosa.

Ti sto assumendo stai usando variabili int a causa della mancanza di cast espliciti nella vostra espressione. Se stai usando un tipo int per le variabili: start_pos dati e la lunghezza; si dovrebbe utilizzare 32, invece di 16, dal momento che int di sono valori a 32 bit.

Anche se avete intenzione di utilizzare i tipi integer primitivi come int, brevi o di byte, ricordate che questi tipi primitivi sono complemento a due che sono segno-esteso, il che significa che se si fa uno spostamento a destra su numeri negativi come ~ 0 ( restituisce -1), quelli saranno aggiunti sul bit di ordine superiore (bit di segno) invece di zeri.

Per esempio:

1111 1111 1111 1111 1111 1111 1111 1000        
>>1
1111 1111 1111 1111 1111 1111 1111 1100 

Ora tornando al tuo problema. L'idea generale è quella di essere in grado di fare una:

data & mask

Ora, generando la maschera è un po 'complicato sui tipi di dati firmati. Avrebbe senso per generare la maschera utilizzando:

(~0 << (32 - length) >> (32 - length - start_pos))

Ma questo non funzionerà ovviamente a causa della estensione del segno.

Vorrei suggerire che invece di utilizzare shift destro >>, uso ruotare operatore >>> questo modo, invece di quelli accodato sul bit di ordine superiore, l'operatore rotazione aggiungerà il bit di ordine inferiore.

Per esempio:

1111 1111 1111 1111 1111 1111 1111 1000        
>>>1
0111 1111 1111 1111 1111 1111 1111 1100 

così ...

mask = (~0 << 32-length >>> 32-length-start_pos)

E la tua risposta definitiva potrebbe essere simile a:

(data & (~0 << 32-length >>> 32-length-start_pos)) >>> start_pos

L'operazione di rotazione esterna sposta i dati mascherati ai bit di ordine inferiore.

Altri suggerimenti

Non certo perché è necessario utilizzare breve. Ecco una soluzione che utilizza a lungo.

public static long getBits(long data, int p, int n) {
    assert p >= 0 && p < 64;
    assert n >= 0 && n < 64;
    return (data >> p) & ((1 << n) - 1);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top