Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice to use bit operations to set some flags

I would like to turn on/off 3 stars that represent a level of difficulty. I don't want to make usage of several if condition, would it be possible to do so by just using bitwise operation?

Let's say i have declared an enum like this:

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

I would like to find a bit operation that let me find which star to turn on or off:

e.g:

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
like image 592
tiguero Avatar asked Oct 25 '12 21:10

tiguero


3 Answers

In the case if you want to have 3 bits to save your stars states, like instead of having three boolean flags, than you should do:

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

Difficulty state = 0; // default

To set Easy:

state |= DifficultyEasy;

To add Challenging:

state |= DifficultyChallenging;

To reset Easy:

state &= ~DifficultyEasy;

To know is Challenging set:

BOOL isChallenging =  DifficultyChallenging & state;

In the case somebody needs an explanation how it works:

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)
like image 139
Ezeki Avatar answered Sep 17 '22 21:09

Ezeki


You would want to do something like this:

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

And then to check it:

- (void) setStarsWithDifficulty:(Difficulty)diff
{
    star0 = (diff & (EASY | MODERATE | CHALLENGING));
    star1 = (diff & (MODERATE | CHALLENGING));
    star2 = (diff & CHALLENGING);
}
like image 42
Tobi Avatar answered Sep 17 '22 21:09

Tobi


Are you talking about something like:

star0 = 1
star1 = value & CHALLENGING || value & MODERATE
star2 = value & CHALLENGING
like image 43
Nathan Villaescusa Avatar answered Sep 19 '22 21:09

Nathan Villaescusa