0

I have a maths issue within my program. I think the problem is simple but I'm not sure what terms to use, hence my own searches returned nothing useful.

I receive some values in a method, the only thing I know (in terms of logic) is the numbers will be something which can be duplicated.

In other words, the numbers I could receive are predictable and would be one of the following

1
2
4
16
256
65536
etc

I need to know at what index they appear at. In othewords, 1 is always at index 0, 2 at index 1, 4 at index 3, 16 is at index 4 etc.

I know I could write a big switch statement but I was hoping a formula would be tidier. Do you know if one exists or any clues as the names of the math forumula's I'm using.

Matt Seymour
  • 8,880
  • 7
  • 60
  • 101
Dave
  • 8,163
  • 11
  • 67
  • 103

4 Answers4

4

The numbers you listed are powers of two. The inverse function of raising a number to a power is the logarithm, so that's what you use to go backwards from (using your terminology here) a number to an index.

var num = 256;
var ind = Math.Log(num, 2);

Above, ind is the base-2 logarithm of num. This code will work for any base; just substitute that base for 2. If you are only going to be working with powers of 2 then you can use a special-case solution that is faster based on the bitwise representation of your input; see What's the quickest way to compute log2 of an integer in C#?

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
  • I actually looked at Logs on the calculator as I guessed something along these lines, but I would never have worked that out. Again Jon, thank you. – Dave Nov 07 '13 at 13:31
  • In this case "4" will not fit in index `[3]` :) – ALZ Nov 07 '13 at 14:00
2

Try

Math.Log(num, base)

where base is 2 MSDN: http://msdn.microsoft.com/en-us/library/hd50b6h5.aspx

Logarithm will return to You power of base from you number. But it's in case if your number really are power of 2, otherwise you have to understand exactly what you have, what you need It also look like numbers was powered to 2 twice, so that try this:

private static int getIndexOfSeries(UInt64 aNum)
{ 
    if (aNum == 1)
        return 0;
    else if (aNum == 2)
        return 1;
    else
    {
        int lNum = (int)Math.Log(aNum, 2);
        return 1+(int)Math.Log(lNum, 2);
    }
}

Result for UInt64[] Arr = new UInt64[] { 1, 2, 4, 16, 256, 65536, 4294967296 } is:

Num[0] = 1
Num[1] = 2
Num[2] = 4
Num[3] = 16
Num[4] = 256
Num[5] = 65536
Num[6] = 4294967296 //65536*65536

where [i] - index

ALZ
  • 1,997
  • 2
  • 27
  • 44
1

You should calculate the base 2 logarithm of the number

1

Hint: For the results:

0 2
1 4
2 16
3 256
4 65536
5 4294967296
etc.

The formula is, for a give integer x:

Math.Pow(2, Math.Pow(2, x));

that is

2 to the power (2 to the power (x) )

Once the formula is known, one could solve it for x (I won't go through that since you already got an answer).

NoChance
  • 5,632
  • 4
  • 31
  • 45