Question

Je suis en train d'écrire une fonction courte getBits (données short, int p, int n)

J'ai essayé:

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

Cela fonctionne pour getBits ((courts) 0x7000, 0, 4), mais si je devais remplacer le 7 avec 8 je reçois une valeur négative.

Était-ce utile?

La solution

Il y a quelques choses à retenir sur les types de données Java, pour faire ce travail chose.

Je suppose que vous utilisez des variables int en raison de l'absence de moulages explicites dans votre expression. Si vous utilisez un type int pour vos variables: données start_pos et longueur; vous devriez utiliser 32 au lieu de 16, car int sont des valeurs de 32 bits.

Aussi, si vous allez utiliser des entiers types primitifs comme int, court ou octet, rappelez-vous que ces types primitifs sont le complément de deux qui sont étendus signe, ce qui signifie que si vous faites un décalage vers la droite sur les nombres négatifs comme ~ 0 ( Equivaut à -1), les seront ajoutés sur le bit d'ordre supérieur (bit de signe) au lieu de zéros.

Par exemple:

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

Maintenant, pour revenir à votre problème. L'idée générale est de pouvoir faire:

data & mask

Maintenant, la génération du masque est un peu délicat sur les types de données signés. Il serait logique de générer le masque en utilisant:

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

Mais cela ne fonctionnera pas bien sûr à cause de l'extension de signe.

je suggère qu'au lieu d'utiliser déplacement vers la droite >>, utilisez rotation opérateur >>> ainsi au lieu de ceux d'être ajouté sur le bit d'ordre supérieur, l'opérateur rotate ajoutera le bit d'ordre inférieur.

Par exemple:

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

...

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

Et votre réponse finale ressemblerait à quelque chose comme:

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

L'opération de rotation la plus extérieure se déplace données masquées aux bits d'ordre inférieur.

Autres conseils

Je ne sais pas pourquoi vous devez utiliser courte. Voici une solution en utilisant longtemps.

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);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top