Бит-маска: как определить, установлен ли только один бит

Если у меня есть базовая битмаска...

cat = 0x1;
dog = 0x2;
chicken = 0x4;
cow = 0x8;

// OMD has a chicken and a cow
onTheFarm = 0x12;

... как я могу проверить, установлено ли только одно животное (то есть один бит)?

Значение onTheFarm должно быть 2 n но как я могу проверить это программно (желательно в Javascript)?

Ответы

Ответ 1

Вы можете подсчитать количество бит, которые заданы в неотрицательном целочисленном значении с помощью этого кода (адаптирован к JavaScript из этого ответа):

function countSetBits(i)
{
    i = i - ((i >> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
    return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}

Он должен быть намного эффективнее, чем рассматривать каждый бит отдельно. Однако это не работает, если бит знака установлен в i.

EDIT (весь кредит для комментария Pointy):

function isPowerOfTwo(i) {
    return i > 0 && (i & (i-1)) === 0;
}

Ответ 2

Понемногу нужно проверять, с функцией более или менее:

function p2(n) {
  if (n === 0) return false;
  while (n) {
    if (n & 1 && n !== 1) return false;
    n >>= 1;
  }

  return true;
}

Некоторые наборы инструкций процессора включают в себя операцию "счетные бит" (старинная серия CDC Cyber ​​была одной). Это полезно для некоторых структур данных, реализованных как битовые коллекции. Если у вас есть набор, реализованный как целая цепочка, с позициями битов, соответствующими элементам заданного типа данных, тогда получение мощности включает в себя подсчет бит.

edit wow глядя в ответ Теда Хоппа, я наткнулся на это:

function p2(n) {
  return n !== 0 && (n & (n - 1)) === 0;
}

Что из эта потрясающая коллекция "трюков" . Такие вещи, как эта проблема, являются вескими основаниями для изучения теории чисел: -)

Ответ 3

Если вы хотите посмотреть, установлен ли только один бит, вы можете использовать логарифмы следующим образом:

var singleAnimal = (Math.log(onTheFarm) / Math.log(2)) % 1 == 0;

Math.log(y) / Math.log(2) находит x в 2^x = y, а x % 1 сообщает нам, что x - целое число. x будет только целым числом, если установлен один бит, и, таким образом, выбрано только одно животное.