Для этого есть простой трюк:
0
Обратите внимание, что эта функция будет отчитываться 2
за 0
, что не сила 2
. Если вы хотите исключить это, вот как это сделать:
bool IsPowerOfTwo(ulong x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}
объяснение
Прежде всего побитовое двоичное bool b = оператор IsPowerOfTwo ( 4 ) из определения MSDN:
Бинарные и операторы предопределены для интегральных типов и bool. Для интегральных типов & вычисляет логическое побитовое И его операндов. Для операндов bool и вычисляет логический AND своих операндов; то есть результатом является возврат ( 4 ! = 0 ) && (( 4 & ( 4 - 1 )) == 0 ); тогда и только тогда, когда оба операнда верны.
Теперь давайте посмотрим, как все это происходит:
Функция возвращает boolean (true / false) и принимает один входящий параметр типа unsigned long (x, в этом случае). Для простоты предположим, что кто-то прошел значение 4 и назвал функцию так:
((4 & (4-1)) == 0)
Теперь мы заменяем каждое вхождение x на 4:
((4 & 3) == 0)
Ну, мы уже знаем, что 4! = 0 оценивает истину, пока что так хорошо. Но что насчет:
4&3
Это, конечно же, означает:
100 = 4
011 = 3
Но что конкретно &
?
Бинарное представление 4 равно 100, а двоичное представление 3 равно 011 (помните, что & берет двоичное представление этих чисел). Таким образом, мы имеем:
1 & 1 = 1
Представьте, что эти значения сложены как элементарное дополнение. &
Оператор говорит , что , если оба значения равны 1 , то результат будет 1, в противном случае он равен 0. Таким образом 1 & 0 = 0
, 0 & 0 = 0
, 0 & 1 = 0
и . Итак, мы делаем математику:100 011 ---- 000
return (4 != 0) && ((4 & 3) == 0);
Результат - просто 0. Итак, мы вернемся и посмотрим, что теперь означает наш оператор return:
return true && (0 == 0);
Это переводит теперь:
return true && true;
true && true
Мы все знаем, что true
это просто true
, и это показывает, что для нашего примера 4 является степенью 2.