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

发布于 2024-12-28 12:30:36 字数 75 浏览 3 评论 0原文

我必须以某种方式保持程序运行,直到指数函数的输出超过输入值,然后将其与指数函数的先前输出进行比较。即使只是伪代码,我该如何做这样的事情?

I somehow have to keep my program running until the output of the exponent function exceeds the input value, and then compare that to the previous output of the exponent function. How would I do something like that, even if in just pseudocode?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

雨落□心尘 2025-01-04 12:30:36
  1. 求给定数以 2 为底的对数 => x := log(2, input)
  2. 将步骤1中获取的值向上和向下舍入=> y := round(x), z := round(x) + 1
  3. 找到 2^y, 2^z,将它们与输入进行比较并选择更适合的一个
  1. Find logarithm to base 2 from given number => x := log (2, input)
  2. Round the value acquired in step 1 both up and down => y := round(x), z := round(x) + 1
  3. Find 2^y, 2^z, compare them both with input and choose the one that suits better
冷情 2025-01-04 12:30:36

根据您使用的语言,您可以使用按位运算轻松完成此操作。您需要设置的单个 1 位大于输入值中设置的最高一位的值,或者设置为输入值中设置的最高一位的值。

如果您确实将最高设置位以下的所有位设置为 1,则添加 1,最终得到下一个更大的 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 了解其他类似的技巧。

Depending on which language you're using, you can do this easily using bitwise operations. You want either the value with a single 1 bit set greater than the highest one bit set in the input value, or the value with the highest one bit set in the input value.

If you do set all of the bits below the highest set bit to 1, then add one you end up with the next greater power of two. You can right shift this to get the next lower power of two and choose the closer of the two.

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

See Bit Twiddling Hacks for other similar tricks.

小猫一只 2025-01-04 12:30:36

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

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

没有显式循环,并且肯定比使用 Math.pow 的解决方案更有效。如果不查看编译器为 numberOfLeadingZeros 生成的代码,很难说更多。

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

Apart from the looping there's also one solution that may be faster depending on how the compiler maps the nlz instruction:

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

No explicit looping and certainly more efficient than the solutions using Math.pow. Hard to say more without looking what code the compiler generates for numberOfLeadingZeros.

With that we can then easily get the lower power of 2 and then compare which one is nearer - the last part has to be done for each solution it seems to me.

亢潮 2025-01-04 12:30:36

将 x 设置为 1。

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

,然后返回 x 或 x / 2,以更接近目标的为准。

set x to 1.

while x < target, set x = 2 * x

then just return x or x / 2, whichever is closer to the target.

枫以 2025-01-04 12:30:36
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;
    }
}
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;
    }
}
凯凯我们等你回来 2025-01-04 12:30:36

我将使用 5 作为输入,而不是 50。

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

I will use 5 as input for an easy example instead of 50.

  • Convert the input to bits/bytes, in this case 101
  • Since you are looking for powers of two, your answer will all be of the form 10000...00 (a one with a certain amount of zeros). You take the input value (3 bits) and calculate the integer value of 100 (3 bits) and 1000 (4 bits). The integer 100 will be smaller then the input, the integer 1000 will be larger.
  • You calculate the difference between the input and the two possible values and use the smallest one. In this case 100 = 4 (difference of 1) while 1000 = 8 (difference of 3), so the searched answer is 4
2025-01-04 12:30:36
public static int neareastPower2(int in) {
    return (int) Math.pow(2, Math.round(Math.log(in) / Math.log(2)));
}
public static int neareastPower2(int in) {
    return (int) Math.pow(2, Math.round(Math.log(in) / Math.log(2)));
}
素染倾城色 2025-01-04 12:30:36

下面是一个函数的伪代码,该函数接受输入数字并返回您的答案。

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
}

Here's the pseudo code for a function that takes the input number and returns your answer.

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
}
美人骨 2025-01-04 12:30:36

这是一个按位解决方案——如果出现平局,它将返回 2^N 和 2^(N+1) 的减数。与调用 log() 函数相比,这应该非常快

let mask = (~0 >> 1) + 1

while ( mask > value )
    mask >> 1

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

Here's a bitwise solution--it will return the lessor of 2^N and 2^(N+1) in case of a tie. This should be very fast compare to invoking the log() function

let mask = (~0 >> 1) + 1

while ( mask > value )
    mask >> 1

return ( mask & value == 0 ) ? mask : mask << 1 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文