Округлить до ближайшей степени двух - PullRequest
24 голосов
/ 09 декабря 2010

Существует ли однострочное выражение (возможно, логическое), чтобы получить ближайшее 2^n число для данного целого числа?

Пример: 5,6,7 должно быть 8.

Ответы [ 7 ]

29 голосов
/ 09 декабря 2010

Округлите до следующей более высокой степени двух: см. хиты с переворотами .

In C:

unsigned int v; // compute the next highest power of 2 of 32-bit v

v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
17 голосов
/ 09 декабря 2010

Я думаю, вы имеете в виду следующий ближайший номер 2 ^ n. Вы можете сделать журнал в режиме 2, а затем определить следующее целое значение из него.

Для Java это можно сделать так:

Math.ceil(Math.log(x)/Math.log(2))
6 голосов
/ 09 декабря 2010

Ваши требования немного запутаны, ближайшая степень от 2 до 5 - 4. Если вы хотите получить следующую степень от 2 до числа, то следующее выражение Mathematica делает то, что вам нужно:

2^Ceiling[Log[2, 5]] => 8

Исходя из этого, в большинстве языков программирования было бы несложно определить однострочность.

5 голосов
/ 24 августа 2017

Поскольку заголовок вопроса «Округление до ближайшей степени двух», я подумал, что было бы полезно также включить решение этой проблемы.

int nearestPowerOfTwo(int n)
{
    int v = n; 

    v--;
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    v++; // next power of 2

    int x = v >> 1; // previous power of 2

    return (v - n) > (n - x) ? x : v;
}

В основном он находит обапредыдущая и следующая степень двух, а затем возвращает ближайшую.

4 голосов
/ 09 декабря 2010

Для следующей степени двойки от заданного целого числа x

2^(int(log(x-1,2))+1)

или альтернативно (если у вас нет функции log, принимающей базу аргумент

2^(int(log(x-1)/log(2))+1)

Обратите внимание, что это не работает для x <2 </p>

2 голосов
/ 04 ноября 2015

Это можно сделать, сдвигая вправо на входном номере до тех пор, пока он не станет равным 0, и сохраняя счет сдвигов.Это даст позицию наиболее значимого 1 бита.Получение 2 к степени этого числа даст нам следующую ближайшую степень 2.

public int NextPowerOf2(int number) {
    int pos = 0;

    while (number > 0) {
        pos++;
        number = number >> 1; 
    }
    return (int) Math.pow(2, pos);
}
0 голосов
/ 04 июня 2018

Модифицировано для VBA. NextPowerOf2_1, похоже, не работает. Поэтому я использовал метод цикла. Требуется сдвиг вправо, хотя мудрый оператор.

Sub test()
    NextPowerOf2_1(31)
    NextPowerOf2_2(31)
    NextPowerOf2_1(32)
    NextPowerOf2_2(32)
End Sub

Sub NextPowerOf2_1(ByVal number As Long) ' Does not work
    Debug.Print 2 ^ (Int(Math.Log(number - 1) / Math.Log(2)) + 1)
End Sub

Sub NextPowerOf2_2(ByVal number As Long)
    Dim pos As Integer
    pos = 0
    While (number > 0)
        pos = pos + 1
        number = shr(number, 1)
    Wend

    Debug.Print 2 ^ pos
End Sub
Function shr(ByVal Value As Long, ByVal Shift As Byte) As Long
    Dim i As Byte
    shr = Value
    If Shift > 0 Then
        shr = Int(shr / (2 ^ Shift))
    End If
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...