如何找到给定输入的最接近的2 ^ N值?

时间:2012-01-22 23:18:17

标签: java algorithm exponent

我不得不让程序保持运行,直到指数函数的输出超过输入值,然后将其与指数函数的先前输出进行比较。即使只是伪代码,我该怎么做呢?

9 个答案:

答案 0 :(得分:4)

  1. 从给定数字=>中找到对数2的对数x:= log(2,输入)
  2. 将步骤1中获得的值向上和向下舍入=> y:= round(x),z:= round(x)+ 1
  3. 找到2 ^ y,2 ^ z,将它们与输入进行比较并选择更适合的

答案 1 :(得分:2)

除了循环外,还有一个解决方案可能更快,具体取决于编译器如何映射nlz指令:

public int nextPowerOfTwo(int val) {
   return 1 << (32 - Integer.numberOfLeadingZeros(val - 1)); 
}

没有明确的循环,当然比使用Math.pow的解决方案更有效。如果不查看编译器为numberOfLeadingZeros生成的代码,很难说更多。

然后,我们可以轻松获得2的较低功率,然后比较哪一个更接近 - 在我看来,每个解决方案都必须完成最后一部分。

答案 2 :(得分:2)

根据您使用的语言,您可以使用按位操作轻松完成此操作。您希望将1位设置的值设置为大于输入值中设置的最高1位,或者输入值中设置最高1位的值。

如果您将最高设置位以下的所有位设置为1,那么添加一个最后一个更大的2的幂。您可以右移以获得下一个较低的2的幂,并选择两者中的较近者。

unsigned closest_power_of_two(unsigned value)
{
    unsigned above = (value - 1); // handle case where input is a power of two
    above |= above >> 1;          // set all of the bits below the highest bit
    above |= above >> 2;
    above |= above >> 4;
    above |= above >> 8;
    above |= above >> 16;
    ++above;                      // add one, carrying all the way through
                                  // leaving only one bit set.

    unsigned below = above >> 1;  // find the next lower power of two.

    return (above - value) < (value - below) ? above : below;
}

有关其他类似技巧,请参阅Bit Twiddling Hacks

答案 3 :(得分:1)

将x设为1。

而x <目标,设置x = 2 * x

然后返回x或x / 2,无论哪个更接近目标。

答案 4 :(得分:0)

public static int neareastPower2(int in) {
    if (in <= 1) {
        return 1;
    }
    int result = 2;

    while (in > 3) {
        in = in >> 1;
        result = result << 1;
    }

    if (in == 3) {
        return result << 1;
    } else {
        return result;
    }
}

答案 5 :(得分:0)

我将使用5作为简单示例的输入,而不是50。

  • 将输入转换为位/字节,在本例中为101
  • 由于您正在寻找2的幂,您的答案将全部为10000 ... 00(具有一定数量的零的一个)。您获取输入值(3位)并计算100(3位)和1000(4位)的整数值。整数100将小于输入,整数1000将更大。
  • 您可以计算输入和两个可能值之间的差异,并使用最小值。在这种情况下,100 = 4(差值为1),而1000 = 8(差值为3),因此搜索到的答案为4

答案 6 :(得分:0)

public static int neareastPower2(int in) {
    return (int) Math.pow(2, Math.round(Math.log(in) / Math.log(2)));
}

答案 7 :(得分:0)

这是一个函数的伪代码,它接受输入数字并返回你的答案。

int findit( int x) {
  int a = int(log(x)/log(2));
  if(x >= 2^a + 2^(a-1))
    return 2^(a+1)
  else
    return 2^a
}

答案 8 :(得分:0)

这是一个按位解决方案 - 如果出现平局,它将返回2 ^ N和2 ^(N + 1)的出租方。与调用log()函数

相比,这应该非常快
let mask = (~0 >> 1) + 1

while ( mask > value )
    mask >> 1

return ( mask & value == 0 ) ? mask : mask << 1