当前位置: 首页 > 面试题库 >

如何计算Java中以整数为底的对数2?

公冶高义
2023-03-14
问题内容

我使用以下函数为整数计算对数基数2:

public static int log2(int n){
    if(n <= 0) throw new IllegalArgumentException();
    return 31 - Integer.numberOfLeadingZeros(n);
}

它是否具有最佳性能?

有人知道为此目的准备好了J2SE API函数吗?

UPD1 对于我来说,令人惊讶的是,浮点运算似乎比整数运算要快。

UPD2 由于有评论,我将进行更详细的调查。

UPD3 我的整数算术函数比Math.log(n)/Math.log(2)快10倍。


问题答案:

如果您正在考虑使用浮点数来帮助进行整数运算,则必须小心。

我通常会尽量避免FP计算。

浮点运算不精确。您永远无法确定会(int)(Math.log(65536)/Math.log(2))得出什么结果。例如,Math.ceil(Math.log(1<<29) / Math.log(2))在我的PC上为30,数学上应该恰好为29。我没有找到x
(int)(Math.log(x)/Math.log(2))失败的值(只是因为只有32个“危险”值),但这并不意味着它将起作用在任何PC上都是相同的方式。

此处的常用技巧是在四舍五入时使用“
epsilon”。喜欢(int)(Math.log(x)/Math.log(2)+1e-10)永远都不会失败。选择这种“ε”不是一件容易的事。

使用更一般的任务进行更多的演示-尝试实现int log(int x, int base)

测试代码:

static int pow(int base, int power) {
    int result = 1;
    for (int i = 0; i < power; i++)
        result *= base;
    return result;
}

private static void test(int base, int pow) {
    int x = pow(base, pow);
    if (pow != log(x, base))
        System.out.println(String.format("error at %d^%d", base, pow));
    if(pow!=0 && (pow-1) != log(x-1, base))
        System.out.println(String.format("error at %d^%d-1", base, pow));
}

public static void main(String[] args) {
    for (int base = 2; base < 500; base++) {
        int maxPow = (int) (Math.log(Integer.MAX_VALUE) / Math.log(base));
        for (int pow = 0; pow <= maxPow; pow++) {
            test(base, pow);
        }
    }
}

如果我们使用最直接的对数实现,

static int log(int x, int base)
{
    return (int) (Math.log(x) / Math.log(base));
}

打印:

error at 3^5
error at 3^10
error at 3^13
error at 3^15
error at 3^17
error at 9^5
error at 10^3
error at 10^6
error at 10^9
error at 11^7
error at 12^7
...

为了完全消除错误,我必须添加介于1e-11和1e-14之间的epsilon。在测试之前,您能告诉这个吗?我绝对不能。



 类似资料:
  • 问题内容: 从有关对数的numpy文档中,我发现了以 e ,2和10为底取对数的函数: 但是,如何在numpy中使用以 n 为底的对数(例如42)? 问题答案: 要使用自定义底数获取对数,请使用: 要使用自定义底数获取对数,请使用: 如您所料,请注意默认情况下。 提醒一下,对数基数更改规则是:

  • 问题内容: 我正在寻找一种Python方式来计算正整数的二进制表示形式中的尾随零数(这将指示最大幂除而无余数)。 一个简单的解决方案: 但是,为了以更Python化的方式进行操作,我认为我可以利用: ,它给出的二进制表示形式 ,它给出了的反向二进制表示形式 因此,我的问题可以简化为对字符串中的尾随零进行计数。 有任何单一陈述的方式可以做到这一点吗? 我的最终目标是一种Python的方法,用于计算其

  • 问题内容: Java中还有其他方法可以计算整数的幂吗? 我现在使用,但是它返回一个,这通常是很多工作,并且在您只想使用s 时看起来不太干净(那么幂也会总是产生)。 有没有像Python 一样简单的东西? 问题答案: 整数只有32位。这意味着其最大值为。如您所见,对于非常小的数字,您很快就会得到不能再用整数表示的结果。这就是使用的原因。 如果要任意整数精度,请使用。但这当然效率较低。

  • 问题内容: 标题几乎可以自我解释。:) 问题答案: 如果它适合/ ,只需检查模10的数字是否为0并保留一个计数器: 如果太大而无法容纳,请将其存储在a中并从最后一个字符开始计数零:

  • 问题内容: 我正在编写一个程序,计算ISBN号码的校验位。我必须将用户的输入(一个ISBN的9位数字)读取到一个整数变量中,然后将最后一位数字乘以2,将最后一位数字乘以3,依此类推。我如何将整数“拆分”为其组成位数?由于这是一项基本的家庭作业,因此我不应该使用列表。 问题答案: 只是用它创建一个字符串。 够了 现在您可以对其进行迭代: 或者您可以将其切片: 或更妙的是,不要将用户的输入转换为整数(

  • 所以,这不是关于如何计算数字中的数字。它是如何计算每一个有多少。说: 多少个0,多少个1等等,我想把它放到树形图中 那我该怎么做呢? 数组将是任意大小的,所以我想我可以循环通过它,对于每个新的int,检查每个数字,如果那么等。但不确定如何增加KV映射中的值。