'How to convert bit to bit shift value

I have a difficulty selector set as an enum (None=0, Easy = 1<<0, Medium = 1<<1, Hard = 1<<2, Expert = 1<<3). Along with this, I have an array of point values I want to assign to these difficulties. So the array has indexes as so. [0, 100, 133, 166, 200].

The tricky bit, is this. I want to grab the index of the array, that is equivalent to the bit shift of the difficulty. So None = 0 (0000)-> Index = 0. Easy = 1 (0001)-> Index = 1. Medium = 2 (0010)-> Index = 2. Hard = 4 (0100) -> Index = 3. Expert = 8 (1000) -> Index = 4.

I tried doing the Square root originally, as I thought that it was powers of two, but quickly realized that it's actually not RAISED to two, it's just a base of two. So that would never work.

I also know I can get this value via a forloop, where I start at 8 (1000) for instance, and keep a counter as I shift right, and keep that going until it hits 0.

int difficulty = (int)LevelSetup.difficulty;
int difficultyIndex = 0;
while(difficulty != 0)
{
    difficultyIndex++;
    difficulty = difficulty >> 1;
}
currScorePerQuestion = ScorePerQuestion[difficultyIndex];

IE. Counter = 0; val = 8. | SHIFT | Counter = 1; val = 4; |SHIFT| Counter = 2; val = 2; |SHIFT| Counter = 3; val = 1; |SHIFT| Counter = 4; val = 0; |END| and we end with a value of 4.

The problem with this is that it seems really messy and overkill, especially if you wanted to go up to 64 bits and have lots of indicies. I just know that there is some kind of algorithm that I could use to convert these very simply. I am just struggling to come up with what that equation is exactly.

Any help is super appreciated, thanks!



Solution 1:[1]

After asking my friends. They came up with and gave me this solution.

As binary works by raising 2 to the nth power. We always have a base of 2, raised to the number that the bit is. So 2^4 is 8 which is the same as 1000 in binary.

Then, using the properties of Logarithms. You can use Log of base 2, which matches our base 2 powers, and take the log of it's value to get the exponential. ie Log2(2^3) = 3. And Log2(2^7) = 7.

luckily for us, binary matches this pattern completely, so a bit mask of (1000) is 8, which is equal to 2^3, so Log2(8) => 3.

To convert a bit into an index, ie (1000) is the 4th bit, so we want an index of 4. Log base 2 of 8 -> Math.Log2(8) = 3. Then to get up to our 0 based index, we just add 1.

This leaves us with the following algorithm:

int difficulty = (int)LevelSetup.difficulty;
currScorePerQuestion = ScorePerQuestion[Math.Log2(difficulty)+1];

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chris McCole