Frage

Ich schreibe eine Funktion kurze GetBITS (kurze Daten, int p, int n)

Ich habe versucht:

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;
}

Dies funktioniert für GetBITS ((kurz) 0x7000, 0, 4), aber wenn ich die 7 mit einem 8 I einen negativen Wert erhalten ersetzen waren.

War es hilfreich?

Lösung

Es gibt ein paar Dinge über Java-Datentypen zu erinnern, dieses Ding funktioniert.

Ich nehme an, Sie verwenden int Variablen wegen des Fehlens von expliziten Abgüsse in Ihrem Ausdruck. Wenn Sie einen int-Typ für Ihre Variablen verwenden: Daten start_pos und Länge; Sie sollten 32 statt 16 verwenden, da int 32-Bit-Werte sind.

Auch wenn Sie integer primitive Typen wie int, kurz oder Byte verwenden werden, denken Sie daran, dass diese primitiven Typen Zweier-Komplement sind die Vorzeichen erweiterten sind, was bedeutet, dass, wenn Sie tun, um eine Verschiebung nach rechts auf negative Zahlen wie ~ 0 ( wertet bis -1), werden diejenigen auf der höheren Bit (Vorzeichenbit) anstelle von Nullen angehängt werden.

Zum Beispiel:

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

Sie jetzt zum Problem zurück. Die allgemeine Idee ist in der Lage sein, ein zu tun:

data & mask
ein bisschen schwierig auf signierte Datentypen

Nun ist die Maske zu erzeugen. Es wäre sinnvoll, um die Maske zu erzeugen mit:

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

Aber das wird natürlich nicht funktionieren, weil die Vorzeichenerweiterung.

Ich würde vorschlagen, dass stattdessen Rechtsverschiebung der Verwendung >>, Gebrauch drehen Operator >>> diese Weise statt, die auf der höheren Bit angehängt, wird das Drehen Bediener den unteren Bit anhängen.

Zum Beispiel:

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

so ...

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

Und Ihre endgültige Antwort würde in etwa so aussehen:

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

Die äußerste Drehvorgang bewegt sich Ihre maskierten Daten zu den Bits niedrigerer Ordnung.

Andere Tipps

Nicht sicher, warum Sie müssen kurz verwenden. Hier ist eine Lösung mit lang.

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);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top