问题描述:

Say I'm given n=32. I want to know what log_2(n) is.

In this case, log_2(32) = 5.

What is the fastest way in general to compute the log of a 2^k number?

I.e.

Given n = 2^k.

log_2(n) = b.

Find b.

Bitwise operations are permitted.

This page gives a half-dozen different ways to do that in C; it should be trivial to change them to C#. Try them all, see which is fastest for you.

http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious

However, I note that those techniques are designed to work for *all* 32 bit integers. If you can guarantee that the input is *always* a power of two between 1 and 2^31 then you can probably do better with a lookup table. I submit the following; I have not performance tested it, but I see no reason why it oughtn't to be pretty quick:

```
static int[] powers = new[] {0, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24,
30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22,
31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5,
20, 8, 19, 18};
static int Log2OfAPower(int x)
{
return powers[((uint)x) % 37]
}
```

The solution relies upon the fact that the first 32 powers of two each have a different remainder when divided by 37.

If you need it to work on longs then use 67 as the modulus; I leave you to work out the correct values for the array.

Commenter LukeH correctly points out that it is bizarre to have a function that purportedly takes the log of a negative number (`1<<31`

is a negative signed integer.) The method could be modified to take a uint, or it could be made to throw an exception or assertion if given a number that doesn't meet the requirements of the method. Which is the right thing to do is not given; the question is somewhat vague as to the exact data type that is being processed here.

CHALLENGE:

Hypothesis: The first n powers of two each have a different modulus when divided by p, where p is the smallest prime number that is larger than n.

If the hypothesis is true then prove it. If the hypothesis is false then provide a counter-example that demonstrates its falsity.

I think that if you guarantee that `n`

will be a power of 2, a quick way to find `b`

would be by converting `n`

to a binary string and finding the index of 1. Special consideration for case when `n = 0`

```
using System.Linq;
...
var binaryStringReversed = Convert.ToString(value, 2).Reverse();
var b = binaryStringReversed.IndexOf("1");
```

EDIT:

```
var b = Convert.ToString(value, 2).Length - 1;
```

您可能感兴趣的文章：

- asp.net mvc - Problem with displaying images in MVC with a virtual directory configured
- python - get_serving_url via remote_api_shell.py
- php - ZEND Classes are not loading on Production server
- jquery - javascript object literal pattern with multiple instances
- android - Can i have alertDialogBox inside another alertDialogbox
- php - Reading a specific line from a text file
- clr - Any implementation of an Unrolled Linked List in C#?
- Finding Hudson Log Files
- Forward to a payment-gateway together with POST data using cURL (or any other PHP server side solution)
- WCF in Winforms app - is it always single-threaded?

随机阅读：

**推荐内容**-

**热点内容**-
- php - Reading a specific line from a text file
- clr - Any implementation of an Unrolled Linked List in C#?
- Finding Hudson Log Files
- WCF in Winforms app - is it always single-threaded?
- git svn - git svn fetch does not fetch a Subversion commit message modified after initial clone
- java me - Why I am getting the bad length exception when I am running this application?
- java - How to get string.format to complain at compile time
- ruby on rails - Trigger observer of parent class on change
- python - Issue with URL pattern in Django with webmonkey tutorial