【问题标题】:Fastest way to factor powers of two?最快的方法来分解两个幂?
【发布时间】:2013-09-03 15:09:08
【问题描述】:

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

我注意到当以二进制表示时,其中包含 2 次幂的数字很方便:

27959296 = 0b1101010101010000000000000 = 110101010101 * 10000000000000 = 3413 * 2^13

如果我可以将这些零位移出,我将剩下其他因素。在查看了 google、SO 和其他一些地方,并玩了 Wolfram|alpha 之后,我看不到一个很好的方法,除非在每个操作上迭代并除以二/位移位。如果我将其转换为字符串,我也许可以使用字符串操作来拆分这些零。

我试过用日志规则来说明:

log base 2(27959296) = log(3413 * 2^13)/log(2) = 13+ log(3413)/log(2)

但我缺少区分 13 和 log(3413)/log(2) 与 24.73 的逻辑......这将给出一个“简单”的答案。

终于有一个方法numberOfTrailingZeros给了我一个很好的答案,但我不知道它是如何工作的,也不知道它有多快。

这是该方法的 SSCCE(来自 here):

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));  
   }
}

最快的方法是什么?我在位移方面走错了吗?

【问题讨论】:

  • 计算机已经以二进制形式存储了数字,并且可以轻松地将零移开。除了位移和numberOfTrailingZeros,我不会尝试其他任何东西。但是有理由认为这是您程序的瓶颈吗?

标签: java math bit-manipulation


【解决方案1】:

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

【讨论】:

  • 你怎么知道它的速度非常快?
  • 它肯定会比将其转换为 String 来计算尾随零。
  • 因为我已经完成了大量的高性能数学实用程序优化和大量基准测试? IIRC,Integer.numberOfTrailingZeros 实际上可能有一个内在的实现;我想我曾经尝试复制/粘贴它的实现并得到了较慢的结果。
  • 快速 Caliper 基准测试产生以下结果:microbenchmarks.appspot.com/runs/…
  • 移位一个数字比进行任何字符串转换/其他计算更快,因为移位只涉及一个汇编命令,并且所有 CPU,无论多么原始支持移位寄存器(意味着如果向左移位则相乘,或者如果你向右移动,则除以)而不使用其 ALU(算术逻辑单元)进行任何计算。
猜你喜欢
  • 2014-02-21
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-22
相关资源
最近更新 更多