如果我有一个数字 a ,我希望 b 中的 x 的值= 2 ^ x ,其中 b 是下一个大于 a 的2的幂。
如果您错过了标记,则为Java, a 为int。我正在寻找最快的方法来做到这一点。我的解决方案就是使用bit-twiddling来获取 b ,然后执行(int)(log( b )/ log(2)),但我觉得有是一个更快的方法,不涉及划分两个浮点数。
答案 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);