-1

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!

Chris McCole
  • 59
  • 2
  • 15
  • 1
    Give that method a good, meaningful name and you're done. It's actually *underkill* compared to your answer below. Don't try to get fancy. Use the bitwise operators for their purpose. – madreflection May 16 '22 at 20:31

1 Answers1

0

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];
Chris McCole
  • 59
  • 2
  • 15
  • Don't do this. Just don't. Although it's mathematically correct, it's using a math function that's costly, plus someone looking at it is going to say, "why is it doing that?" Bit manipulation and testing will be a lot clearer to the *reader* of the code when it's using bitwise operators. I would reject a PR that did this. – madreflection May 16 '22 at 20:34