快速找到2的最近上方指数的指数

时间:2011-03-09 07:17:17

标签: java performance

如果我有一个数字 a ,我希望 b 中的 x 的值= 2 ^ x ,其中 b 是下一个大于 a 的2的幂。

如果您错过了标记,则为Java, a 为int。我正在寻找最快的方法来做到这一点。我的解决方案就是使用bit-twiddling来获取 b ,然后执行(int)(log( b )/ log(2)),但我觉得有是一个更快的方法,不涉及划分两个浮点数。

9 个答案:

答案 0 :(得分:36)

a == 0 ? 0 : 32 - Integer.numberOfLeadingZeros(a - 1)怎么样?这完全避免了浮点数。如果您知道a永远不会为0,那么您可以不用第一部分。

答案 1 :(得分:10)

如果有人正在寻找Andy提到的一些“苦涩”的代码,那可能看起来像这样:(如果人们有更好的方法,你应该分享!)

    public static int nextPowerOf2(final int a)
    {
        int b = 1;
        while (b < a)
        {
            b = b << 1;
        }
        return b;
    }

答案 2 :(得分:4)

不一定更快,但是一个班轮:

 animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)

答案 3 :(得分:0)

如果你需要一个适用于整数或浮点的答案,这两个都应该有效:

我认为Math.floor(Math.log(a) * 1.4426950408889634073599246810019) + 1是你最好的选择,如果你不想做点蠢事。

如果你想要旋转,你可以使用Double.doubleToLongBits(a),然后只提取指数。我在想((Double.doubleRawToLongBits(a) >>> 52) & 0x7ff) - 1022应该做的伎俩。

答案 4 :(得分:0)

分而治之怎么样?如:

b = 0;
if (a >= 65536){a /= 65536; b += 16;}
if (a >= 256){a /= 256; b += 8;}
if (a >= 16){a /= 16; b += 4;}
if (a >= 4){a /= 4; b += 2;}
if (a >= 2){a /= 2; b += 1;}

假设a是无符号的,则除数应该只是位移。

具有32个叶子的二进制IF树应该更快,在5次比较中得到答案。类似的东西:

if (a >= (1<<0x10)){
  if (a >= (1<<0x18)){
    if (a >= (1<<0x1C)){
      if (a >= (1<<0x1E)){
        if (a >= (1<<0x1F)){
          b = 0x1F;
        } else {
          b = 0x1E;
        }
      } else {
        if (a >= (1<<0x1D)){
          b = 0x1D;
        } else {
          b = 0x1C;
        }
      }
   etc. etc.

答案 5 :(得分:0)

只需执行以下操作:

使用此方法(从hdcode修改)提取最高位:

int msb(int x) {
   if (pow2(x)) return x;
   x = x | (x >> 1);
   x = x | (x >> 2);
   x = x | (x >> 4);
   x = x | (x >> 8);
   x = x | (x >> 16);
   x = x | (x >> 24);
   return x - (x >> 1);
}

int pow2(int n) {
   return (n) & (n-1) == 0;
}

将两个函数组合到此函数中以获得数字'b',即给定数字'a'的2的下一个幂:

int log2(int x) {
    int pow = 0;
    if(x >= (1 << 16)) { x >>= 16; pow +=  16;}
    if(x >= (1 << 8 )) { x >>=  8; pow +=   8;}
    if(x >= (1 << 4 )) { x >>=  4; pow +=   4;}
    if(x >= (1 << 2 )) { x >>=  2; pow +=   2;}
    if(x >= (1 << 1 )) { x >>=  1; pow +=   1;}
    return pow;
}
亲切的问候, 戴夫

答案 6 :(得分:0)

Java提供了一个向下舍入到最接近2的幂的函数。因此a!=Integer.highestOneBit(a)?2*Integer.highestOneBit(a):a是一个稍微漂亮的解决方案,假设a是正数。

Integer.highestOneBit(a)存储在变量中可能会进一步提高性能和可读性。

答案 7 :(得分:-1)

要添加Jeremiah Willcock的答案,如果你想要2的力量值,那么你会想要:

(int) Math.pow(2, (a == 0) ? 0 : 32 - Integer.numberOfLeadingZeros(numWorkers));

答案 8 :(得分:-1)

这是我的相同代码。这会更快吗?

 int a,b,x,y;
    Scanner inp = new Scanner(System.in);
    a = inp.nextInt();
    y = (int) (Math.log(a)/Math.log(2));
    x = y +1;
    System.out.println(x);