说我给了n = 32。我想知道log_2(n)是什么。 在这种情况下,log_2(32)= 5。
计算2 ^ k数字日志的最快方法是什么?
即。 给定n = 2 ^ k。 log_2(n)= b。 找到b。
允许按位操作。
答案 0 :(得分:15)
这个页面提供了六种不同的方法来做到这一点;将它们改为C#应该是微不足道的。全部尝试,看看哪个最快。
http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
但是,我注意到这些技术旨在用于所有 32位整数。如果您可以保证输入始终 2的幂,介于1和2 ^ 31之间,那么您可以使用查找表做得更好。我提交以下内容;我没有对它进行性能测试,但我认为没有理由说它不应该很快:
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]
}
解决方案依赖的事实是,当除以37时,前两个的32个幂都有不同的余数。
如果你需要它来长时间工作,那么使用67作为模数;我让你为数组找出正确的值。
评论者LukeH正确地指出,拥有一个据称取负数的日志(1<<31
是负的有符号整数)的函数是奇怪的。)该方法可以被修改为取一个uint,或者它如果给出的数字不符合方法的要求,可以使异常或断言抛出。没有给出哪个是正确的做法;关于这里正在处理的确切数据类型,这个问题有些模糊。
CHALLENGE:
假设:当除以p时,每个2的前n个幂具有不同的模数,其中p是大于n的最小素数。
如果假设为真,则证明它。如果假设是假的,那么提供一个证明其虚假的反例。
答案 1 :(得分:1)
我认为,如果您保证n
将是2的幂,则快速查找b
的方法是将n
转换为二进制字符串并查找索引1. n = 0
using System.Linq;
...
var binaryStringReversed = Convert.ToString(value, 2).Reverse();
var b = binaryStringReversed.IndexOf("1");
编辑:
var b = Convert.ToString(value, 2).Length - 1;