Java 计算小于N的基2对数的最大整数

Java 计算小于N的基2对数的最大整数,java,algorithm,math,logarithm,Java,Algorithm,Math,Logarithm,我一直在阅读《算法》第四版,它定义了一个问题如下: 编写一个静态方法lg(),该方法将int值N作为参数,并返回不大于Java中N的以2为底对数的最大int。不要使用数学 我发现了以下解决方案: public static int lg(int N) { int x = 0; for (int n = N; n > 1; n/= 2) x++; return x; } 我想知道为什么这个解决方案有效。为什么连续除以2会让我们找到小于参数以2为底对数的最大整数?我确

我一直在阅读《算法》第四版,它定义了一个问题如下:

编写一个静态方法
lg()
,该方法将
int
N
作为参数,并返回不大于Java中
N
的以2为底对数的最大
int
。不要使用数学

我发现了以下解决方案:

public static int lg(int N) {
    int x = 0;
    for (int n = N; n > 1; n/= 2) x++;
    return x;
}
我想知道为什么这个解决方案有效。为什么连续除以2会让我们找到小于参数以2为底对数的最大整数?我确实了解Java,只是不了解这个特定算法的工作原理


谢谢。

这与指数和对数的性质有关。你需要的主要观察是

2lgn=n

因为对数是指数的倒数。重新排列该表达式会使

1=n/2lg n

换言之,lg n的值是必须将n除以2才能将其降为1的次数。顺便说一句,在研究算法时,这是一个非常好的直觉,因为日志项总是出现在这样的上下文中


关于整数除法的工作原理,这里还有其他一些细微差别,但这是该代码工作原理背后的基本思想。

它从对数恒等式
log(a/b)=log(a)-log(b)

您正在搜索最大整数
x
,以便:

x <= log2(n)

因此,
x
是在到达
1
之前,你将
n
除以
2
的次数。答案纯粹是数学

日志₂(n) =ln(n)/ln(2)=x

通过应用指数法则:

ln(n)=ln(2)*(x)

n=2^x


因此,你必须除以2,直到值小于1,才能得到最接近的整数。

我们正在寻找最大的整数x,因此x我投票结束这个问题,因为这是一个关于数学的问题,不是关于编程的。@JoeC你认为我应该在数学堆栈交换上问这个问题吗?我不是该网站的专家,除了给你指出他们的观点以便你做出判断之外,我没有能力提供建议。@JoeC以2为底的x的对数等于x可以除以2达到1的次数,包括银行。lg是指自然对数还是以10为底的对数?我在CS中看到的惯例是,lg指以2为底的对数。您可以通过注意只有以2为底的对数满足上述数学要求来检查这一点。@templatetypedef“建议使用ISO 31-11和ISO 80000-2标准,
lb n
。根据这些标准,
lg n
不应用于二进制对数,因为它是为普通对数
log10 n
保留的。“简言之,当我有疑问的时候,我不知道!我在很多论文中看到了lg约定,通常是在不能与其他日志库混淆的情况下使用的。
x <= log2(n/2) + log2(2)
x <= log2(n/2) + 1
x <= log2(n/4) + 2
x <= log2(n/8) + 3
...
x <= log2(1) + k            
x <= k                   (since log2(1) = 0)