La mejor práctica para usar operaciones de bits para configurar algunas banderas

Me gustaría encender / apagar 3 estrellas que representan un nivel de dificultad. No quiero hacer uso de varios si condición, ¿sería posible hacerlo simplemente usando la operación bit a bit?

Digamos que he declarado una enumeración como esta:

enum { EASY = 0, MODERATE, CHALLENGING } Difficulty; 

Me gustaría encontrar un poco de operación que me permita encontrar qué estrella activar o desactivar:

p.ej:

 level 2 (challenging) star 0 -> 1 star 1 -> 1 star 2 -> 1 level 1 (moderate) star 0 -> 1 star 1 -> 1 star 2 -> 0 level 0 (easy) star 0 -> 1 star 1 -> 0 star 2 -> 0 

Querría hacer algo como esto:

 typedef enum Difficulty : NSUInteger { EASY = 1 << 0, MODERATE = 1 << 1, CHALLENGING = 1 << 2 } Difficulty; 

Y luego para comprobarlo:

 - (void) setStarsWithDifficulty:(Difficulty)diff { star0 = (diff & (EASY | MODERATE | CHALLENGING)); star1 = (diff & (MODERATE | CHALLENGING)); star2 = (diff & CHALLENGING); } 

En el caso de que quiera tener 3 bits para save sus estados de estrellas, como en lugar de tener tres indicadores booleans, de lo que debería hacer:

 typedef enum { DifficultyEasy = 1 << 0, DifficultyModerate = 1 << 1, DifficultyChallenging = 1 << 2 } Difficulty; Difficulty state = 0; // default 

Para configurar Easy:

 state |= DifficultyEasy; 

Para agregar Desafiante:

 state |= DifficultyChallenging; 

Para reiniciar Easy:

 state &= ~DifficultyEasy; 

Para saber es el set desafiante:

 BOOL isChallenging = DifficultyChallenging & state; 

En el caso de que alguien necesite una explicación de cómo funciona:

 1 << x means set x bit to 1 (from right); // actually it means move 0b00000001 left by x, but I said 'set' to simplify it 1 << 5 = 0b00100000; 1 << 2 = 0b00000100; 1 << 0 = 0b00000001; 0b00001111 | 0b11000011 = 0b11001111 (0 | 0 = 0, 1 | 0 = 1, 1 | 1 = 1) 0b00001111 & 0b11000011 = 0b00000011 (0 & 0 = 0, 1 & 0 = 0, 1 & 1 = 1) ~0b00001111 = 0b11110000 (~0 = 1, ~1 = 0) 

¿Estás hablando de algo como:

 star0 = 1 star1 = value & CHALLENGING || value & MODERATE star2 = value & CHALLENGING 
 #define STAR0 1 #define STAR1 2 #define STAR2 4 #define EASY STAR0 #define MODERATE STAR1|STAR0 #define CHALLENGING STAR0|STAR1|STAR2 

La detección de un valor d con y y comparar con 0 producirá el mapeo requerido, algunas de las muestras anteriores le darán el valor asignado en su lugar, eche un vistazo:

  int d = EASY; NSLog(@"Star 0 %d",(d&STAR0)!=0); NSLog(@"Star 1 %d",(d&STAR1)!=0); NSLog(@"Star 2 %d",(d&STAR2)!=0); d=MODERATE; NSLog(@"Star 0 %d",(d&STAR0)!=0); NSLog(@"Star 1 %d",(d&STAR1)!=0); NSLog(@"Star 2 %d",(d&STAR2)!=0); d=CHALLENGING; NSLog(@"Star 0 %d",(d&STAR0)!=0); NSLog(@"Star 1 %d",(d&STAR1)!=0); NSLog(@"Star 2 %d",(d&STAR2)!=0);