两种因素的最快方式?

Pur*_*ret 2 java math bit-manipulation

我正在编写一些代码,我希望能够快速分解出2的幂.

当用二进制表示时,我注意到有些功能为2的数字方便的东西:

27959296 = 0b1101010101010000000000000 = 110101010101 * 10000000000000 = 3413 * 2^13
Run Code Online (Sandbox Code Playgroud)

如果我可以将这些零点移位,我会留下其他因素.在浏览了谷歌,SO和其他一些地方,并使用Wolfram | alpha之后,我无法看到一个很好的方法来做到这一点,而无需迭代并在每个操作上进行两位/一位移位.如果我将它转换为字符串,我可能可以使用字符串操作来拆分这些零.

我尝试过使用日志规则来说:

log base 2(27959296) = log(3413 * 2^13)/log(2) = 13+ log(3413)/log(2)
Run Code Online (Sandbox Code Playgroud)

但我错过了区分13和log(3413)/log(2)24.73 之间的逻辑......这将给出一个"简单"的答案.

最后有一种方法numberOfTrailingZeros给了我一个很好的答案,但我不知道它是如何在引擎盖下,也不知道它有多快.

这是该方法的SSCCE(从这里开始):

import java.lang.*;

public class IntegerDemo {

   public static void main(String[] args) {

     int i = 27959296;
     System.out.println("Number = " + i);

     /* returns the string representation of the unsigned integer value 
     represented by the argument in binary (base 2) */
     System.out.println("Binary = " + Integer.toBinaryString(i));

     /* returns the number of zero bits following the lowest-order 
     ("rightmost") one-bit */
     System.out.print("Number of trailing zeros = ");
     System.out.println(Integer.numberOfTrailingZeros(i));  
   }
}
Run Code Online (Sandbox Code Playgroud)

什么是最快的方法?我是否采用位移错误方式?

Lou*_*man 6

Integer.numberOfTrailingZeros是快速的,并i >> Integer.numberOfTrailingZeros(i)可能是最快的替代方案.

  • 它肯定会胜过将其转换为 `String` 来计算尾随零。 (2认同)
  • 因为我已经完成了大量高性能数学实用程序优化和大量基准测试?IIRC,`Integer.numberOfTrailingZeros` 实际上可能有一个内在的实现;我想我曾经尝试复制/粘贴它的实现并得到了较慢的结果。 (2认同)