6
votes

bit le plus significatif bitwise

Je veux trouver le bit le plus significatif qui est défini sur 1 . J'ai essayé toutes les tâches possibles à partir de & pour oriser tous les bits à partir de 1 à 31 et cela ne fonctionne pas.

Comme si 1000000 J'aimerais avoir 7 .


4 commentaires

Qu'avez-vous essayé en détail? Quel était le résultat?


J'ai fait tout le comte + = 1 & (~ x >> 1-31); et cela m'a donné des nombres différents de ce que je m'attendais à vouloir le bit le plus significatif qui soit 1 et c'est ça


Comment les nombres négatifs devraient-ils être traités?


Peu importe j'ai besoin du bit le plus significatif qui soit 1 c'est tout. Donc, même si j'ai -2, j'ai encore besoin du bit le plus significatif avec le 1


10 Réponses :


18
votes

0 commentaires

-3
votes
if( value | 0x40 ) return 7;
else if( value | 0x20 ) return 6;
else if( value | 0x10 ) return 5;
else if( value | 0x8 ) return 4;
else if( value | 0x4 ) return 3;
else if( value | 0x2 ) return 2;
else if( value | 0x1 ) return 1;

1 commentaires

Qu'est-il arrivé de revenir 8 à 31?



0
votes

Pas le plus efficace, peut-être, mais cela devrait fonctionner: xxx


1 commentaires

Non, juste non. Oui ça marche, mais j'ai-t-il gaspillé.



-1
votes

juste pour ajouter une autre approche xxx


2 commentaires

Vous voulez probablement saisir un int plutôt qu'un octet .


Je ne pense pas que votre point de départ est correct. Ce code donne la même réponse pour integer.max_value comme pour les nombres négatifs.



4
votes

Si vous insistez sur directement à l'aide des opérateurs bitwises, vous pouvez essayer quelque chose comme ceci: xxx

Nous initialisons le masque à 1 << 31 parce que cela représente un 1 suivi de 31 0. Nous utilisons cette valeur pour tester si l'index 31 (32e Spot) est un 1. Lorsque nous et cette valeur avec Myint , nous obtenons un 0 si le bit correspondant est défini dans myint . Si tel est le cas, nous retournons que bitindex . Sinon, alors nous déplacons le masque à droite par 1 et essayez à nouveau. Nous répétons que nous manquons de lieux de décalage, auquel cas cela signifie qu'aucun des bits n'a été défini (peut-être que vous souhaitez lancer une exception ici au lieu de retourner -1).

Notez que cela reviendra La valeur 0 pour 1 et 6 pour 64 ( 1000000 en binaire). Vous pouvez ajuster que si vous préférez. Notez également que j'ai utilisé l'opérateur droit non signé plutôt que le changement de droite signé. C'est parce que l'intention ici est de traiter des bits brutes plutôt que de leur interprétation signée, mais peu importe dans ce cas, car toutes les valeurs négatives se termineront dans la première itération de la boucle avant de se déplacer.


3 commentaires

En fait, l'utilisation de l'opérateur de changement de droite non signé est importante. Si myint est pas négatif, vous devrez alors déplacer masque et il démarre comme une valeur négative.


Vous avez raison que masque aura toujours un 1 dirigeant qui n'appartient pas si le changement de droite signé est utilisé (car masque commence comme négatif). Cependant, cela n'affecte pas les résultats de ma mise en œuvre car lorsque myint n'est pas négatif, ce 1 bit superflu est toujours en train d'être et avec un 0 (c.-à-d. Le bit des signes de myint , que nous venons de dire était positif).


Bon point! Je n'avais pas travaillé à travers les conséquences d'avoir conduit 1s dans masque , qui (comme vous le soulignez) ne sont pas précisément rien.



2
votes

L'approximation successive minimisera les itérations à cinq boucles: xxx


0 commentaires

8
votes

Bien qu'il y ait une réponse acceptée, j'ai un autre moyen de partager, ce que je pense est plus facile.

Si vous souhaitez utiliser des opérations bitwises, voici la voie. Fondamentalement, je suis en train de changer l'entier jusqu'à ce qu'il soit zéro. Aucun masque n'est requis. p>

private static int mostSignificantBit(int myInt){
    if (myInt == 0) return 0;    // special handling for 0
    if (myInt < 0) return 32;    // special handling for -ve

    return (int)(Math.log(myInt)/Math.log(2)) +1;
}


0 commentaires

15
votes

La mise en œuvre slickest que j'ai rencontrée - trois itérations et une recherche de table.

unsigned int msb32(unsigned int x)
{
    static const unsigned int bval[] =
    { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 };

    unsigned int base = 0;
    if (x & 0xFFFF0000) { base += 32/2; x >>= 32/2; }
    if (x & 0x0000FF00) { base += 32/4; x >>= 32/4; }
    if (x & 0x000000F0) { base += 32/8; x >>= 32/8; }
    return base + bval[x];
}


0 commentaires

-1
votes

Utilisez simplement la méthode NumberOtTrarsezeros (valeur) de classe longue ou entière.


0 commentaires

-1
votes

pour le petit format Endian:

((yourByte & yourBitMask) >> msbIndex) && 0x01


0 commentaires