Найдите старший установленный бит

У меня есть 5 разных значений, которые сохраняются как биты, например 10010. Я получаю значение как Int из базы данных (не могу это изменить), поэтому, например, 24 означает 11000. Я знаю, что могу получить самый большой бит здесь, используя

if ((decbin($d) & 16) == 16)

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

Так что в конце концов у меня был бы блок ifs, и если бы было больше битов, блок был бы больше. Есть ли простой способ просто получить «id» (или значение, не имеет значения) старшего бита с 1?


person Flo    schedule 09.02.2011    source источник
comment
Более того, я не знаю, будет ли работать ваш код, так как в руководстве по PHP я вижу, что decbin возвращает строку. Чтобы сделать то, что вы намеревались сделать, вам просто нужно было сделать if(($d & 16) = = 16) и т. д.   -  person Andrea Spadaccini    schedule 09.02.2011


Ответы (3)


Да. Вычислить логарифм числа по основанию 2 и floor его:

$highbit = floor(log($d, 2));

Если $highbit, например, равно 5, это означает, что 5-й бит является старшим битом, установленным в 1.

person Andrea Spadaccini    schedule 09.02.2011
comment
Это круто, но обязательно обратите внимание, что $highbit — это битовый индекс, а не битовая позиция с отсчетом от 1. - person Alexander Smith; 13.08.2020

Старший бит, установленный в целом числе, равен целому логарифму по основанию 2 этого целого числа.

Хотя существует много разных реализаций для выполнения подобных вещей на ассемблере и C и т. д., более или менее эффективно, вероятно, самый простой способ сделать это в PHP — это использовать логарифм.

Функция log(), безусловно, не самый эффективный способ решения проблемы, но, учитывая, что вы используете язык сценариев, она, вероятно, не будет медленнее (и, возможно, быстрее), чем реализация одного из «лучших» алгоритмов. в PHP с 2 дюжинами операторов.

Таким образом:

$highestbit = (int)(log($value,2));

person Damon    schedule 09.02.2011

Интересно... пришлось немедленно проверить на наличие проблем с округлением и не нашел ни одной в диапазоне до 1 000 000, хотя мой тестовый код выявил проблемы для менее нативных баз, таких как 3:

3 ^ 5 = 243, но пол (log (243, 3)) дает 4

person Raffael    schedule 09.02.2011