BitParity - поиск нечетного числа бит в целочисленном

Мне нужно создать функцию bitParity(int x), которая принимает целое число и возвращает 1, если в битовой форме x есть нечетное число 0 и 0.

Пример: bitParity(5) = 0, bitParity(7) = 1

Однако это сложно, так как я могу использовать только битовые операторы по этой проблеме (! ˜ & ˆ | + << >> являются единственными законными). Это означает, что нет циклов, if-then или что-то в этом роде. Можно использовать константы.

До сих пор то, что у меня не работает, но я полагал, что я должен смещать биты целого числа 16, 8 и 4 times и XOR оставшиеся целые числа.

Может кто-нибудь предложить какой-нибудь совет? Спасибо.

Ответ 1

Это правильно решается с помощью цикла. Но вот способ сделать это без.

x = (x & 0x0000FFFF) ^ (x >> 16)
x = (x & 0x000000FF) ^ (x >> 8)
x = (x & 0x0000000F) ^ (x >> 4)
x = (x & 0x00000003) ^ (x >> 2)
x = (x & 0x00000001) ^ (x >> 1)

Изменить: мне не нужен &. Лучшая версия:

x ^= x >> 16
x ^= x >> 8
x ^= x >> 4
x ^= x >> 2
x ^= x >> 1
x &= 1;

Ответ 2

Для 32-битных номеров:

function bitParity(int x) {
   x ^= x >> 16;
   x ^= x >> 8;
   x ^= x >> 4;
   x &= 0xf;
   return (0x6996 >> x) & 1;
}

Примечание * 0x6996 представляет битовый вектор чисел 1, 2, 4, 7, 8, 11, 13 и 14. Все 4-битные значения, которые могут быть представлены нечетным числом битов. В 0x6996 бит устанавливается, если его позиция в векторе соответствует (1, 2, 4, 7, 8, 11, 13 или 14).

Вот почему (0x6996 >> x) & 1 имеет смысл, после сдвига на x это выражение будет приводить к возвращенному 1, только если x равно любому из значений в битовом векторе, то есть нечетное количество битов было задавать.

Ответ 3

Вот одна из моих функций, которые я использовал во время моей работы над бакалаврской диссертацией;)

/** Calculates number of bits in unsigned char
 * @brief Bit count
 * @param input to be checked
 * @return int 0-8
 */
int bitCount( unsigned char input)
{
    static unsigned char count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
    return (int)(
            count[ input & 0x0f] +
            count[ (input >> 4) & 0x0f]
    );
}

Таким образом, общий счетчик для целочисленного 4B будет:

int bytes = bitCount( (unsigned char)((number >> 0)&255))
            + bitCount( (unsigned char)((number >> 8)&255))
            + bitCount( (unsigned char)((number >> 16)&255))
            + bitCount( (unsigned char)((number >> 24)&255));

И четность:

 return bytes%2;
 return bytes&1; // if you preffer

Я всегда хотел повторно использовать эти коды:)

ИЗМЕНИТЬ: Как вы могли заметить, unsigned char (8b) можно разделить на 2 части каждый длиной 4b, что означает 16 значений, которые легко хранить и повторно использовать. Таким образом, вы берете первые 8b из целого числа, разбивая их на две части. Убедитесь, что они оба находятся в интервале <0,15>, и просто получают счетчик бит. Повторите:)