2009-02-09 7 views
22
au niveau du bit

J'ai quatre drapeauxUtilisation des opérateurs sur les drapeaux

Current = 0x1 
Past = 0x2 
Future = 0x4 
All = 0x7 

Dire que je reçois les deux drapeaux passé et l'avenir (setFlags(PAST | FUTURE)). Comment puis-je savoir si Past est dedans? De même, comment puis-je dire que Current n'est pas dedans? De cette façon, je n'ai pas besoin de tester toutes les combinaisons possibles.

Répondre

40

Si vous voulez que tous les bits dans le masque de test pour correspondre:

if((value & mask) == mask) {...} 

Si vous voulez un seul bit dans le masque de test doit correspondre:

if((value & mask) != 0) {...} 

La différence est plus évidente lorsque vous testez une valeur pour plusieurs éléments.

Pour tester l'exclusion:

if ((value & mask) == 0) { } 
+0

Pourriez-vous donner un exemple avec le ~? – Malfist

+0

En fait, peut-être pas nécessaire - updatd –

-1

vous pouvez utiliser ET sur et vérifier si le résultat est le même que vous et avec?

4
if ((flags & PAST) == PAST) 
{ 
    // PAST is there 
} 

if ((flags & CURRENT) != CURRENT) 
{ 
    // CURRENT is not there 
} 
+0

Dommage que ce soit faux (ne compile pas) ...en C# vous avez besoin de parenthèses autour des (flags & CURRENT) –

+4

@Marc Gravell, pourquoi publieriez-vous ce commentaire et ne pas éditer le post pour le gars? – mmcdole

0
(value & Current) == Current 
26

tout d'abord - utiliser les énumérations avec FlagAttribute. C'est pour ça.

[Flags] 
public enum Time 
{ 
    None = 0 
    Current = 1, 
    Past = 2, 
    Future = 4 
    All = 7 
} 

test puis se fait comme ceci:

if ((x & Time.Past) != 0) 

Ou ceci:

if ((x & Time.Past) == Time.Past) 

Ce dernier fonctionnera mieux si était « passé » une combinaison de drapeaux et que vous vouliez tester le centre commercial.

Le réglage est comme ceci:

x |= Time.Past; 

Débranchement est comme ceci:

x &= ~Time.Past; 
+0

Corrigez-moi si je me trompe, je pense que 1 n'est pas approprié pour être utilisé comme valeur de drapeau? Comme toute valeur de drapeau (& Opérateur) avec 1, le résultat est toujours 1. – Roylee

+1

@Roylee - non, c'est une valeur de drapeau parfaitement normale. Cela correspond exactement à un bit. Et pensez-y - par exemple 4 & 1 = 0. –

+0

Icic. got it :) Ensuite, vous devez vous assurer que le reste des ensembles de valeur de drapeau sont * puissance de 2 *, non? – Roylee

9

Vous pouvez également ajouter une méthode d'extension comme celui-ci

enum states { 
    Current = 0x1, 
    Past = 0x2, 
    Future = 0x4, 
    All = 0x7 
    }; 

    static bool Is(this states current, states value) { 
    return (current & value) == value; 
    } 

vous pouvez faire:

if(state.Is(states.Past)) { 
    // Past 
} 
0

Un supplément à la Marc Gravell et Vilx -...

Votre énumération avec indicateur ne doit pas spécifier le montant pour "Tous", il doit simplement inclure vos valeurs existantes. Cela vaut pour toutes les valeurs calculées.

[Flags] 
public enum Time 
{ 
    None = 0, 
    Current = 1, 
    Past = 2, 
    Future = 4, 
    All = Current | Past | Future 
} 

Notez que Vilx- a supprimé l'utilisation de Hexadécimal pour les valeurs. Ceci est important car une fois passé 0x8 vos valeurs devront être conformes à Hex. Vous devriez juste rester en décimal.

Questions connexes