C# 计算log_2(n)的最快方法,其中n的形式为2^k?

C# 计算log_2(n)的最快方法,其中n的形式为2^k?,c#,math,bit-manipulation,C#,Math,Bit Manipulation,假设我得到n=32。我想知道log_2(n)是什么。 在这种情况下,log_2(32)=5 一般来说,计算2^k个数的对数的最快方法是什么 即。 给定n=2^k。 log_2(n)=b。 找到b 允许按位操作。本页给出了在C中实现此操作的六种不同方法;将它们更改为C#应该很简单。试一下,看看哪一个对你来说最快 然而,我注意到,这些技术设计用于所有32位整数。如果您可以保证输入在1和2^31之间始终是2的幂,那么使用查找表可能会做得更好。我提交以下文件:;我还没有对它进行性能测试,但我看不出为什

假设我得到n=32。我想知道log_2(n)是什么。 在这种情况下,log_2(32)=5

一般来说,计算2^k个数的对数的最快方法是什么

即。 给定n=2^k。 log_2(n)=b。 找到b


允许按位操作。

本页给出了在C中实现此操作的六种不同方法;将它们更改为C#应该很简单。试一下,看看哪一个对你来说最快

然而,我注意到,这些技术设计用于所有32位整数。如果您可以保证输入在1和2^31之间始终是2的幂,那么使用查找表可能会做得更好。我提交以下文件:;我还没有对它进行性能测试,但我看不出为什么它不应该非常快:

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]
} 
这个解决方案依赖于这样一个事实,即两个幂的前32个幂除以37时,每个幂都有一个不同的余数

如果你需要它在长杆上工作,那么使用67作为模数;我让您为数组计算正确的值


评论者LukeH正确地指出,有一个据说取负数对数的函数是很奇怪的(
1我认为,如果你保证
n
是2的幂,那么快速找到
b
的方法是将
n
转换为二进制字符串,并找到1的索引。对于
n=0

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


n是受限的吗?例如,它是int还是long?(所以k可能是重复的,我很困惑为什么这个问题得到了一堆赞成票,接着是一堆反对票,现在是-1。这个问题出了什么问题?特别令人困惑的是,它导致了埃里克·利珀特下面的精彩答案。字符串的长度不够长吗s Convert.ToString包含前导零?(编辑--string length-1)我在回答后考虑了它,我认为我只是将“最快的方式”解释为最明显、最容易用最少的代码实现的方式。否则问题将是“什么是最有效的方式…”出于好奇,是否有理由将演员设置为
uint
?你已经假设
x
在1和2**31之间是2的精确幂。@LukeH:我将用一个问题来回答你的问题:什么是(1@LukeH:除非另有说明,否则我假设所有方法都希望采用符合CLS的类型。@Eric:这很公平,尽管声称返回负数日志感觉有点奇怪。在这种情况下,您真正返回的是
lg(2147483648)
而不是
lg(-2147483648)
,可以说,这应该会产生错误。(尽管这两个数字从一个有趣的角度来看是一样的。)@Eric:在你的假设中,你的意思是说2的每一次幂除以P时有不同的余数吗?这是不正确的,一个简单的反例是N=6,P=7:2^2 mod 7≡ 2^5模7=4。
var b = Convert.ToString(value, 2).Length - 1;