Код четности для нечетного числа бит
Я пытаюсь найти четность цепочки битов, чтобы она возвращала 1, если x имеет нечетное число из 0.
Я могу использовать только базовые побитовые операции, и то, что у меня есть, проходит большинство тестов, но мне интересно 2 вещи:
Почему x ^ (x + ~1) работает? Я наткнулся на это, но, похоже, даст вам 1, если есть нечетное количество битов и что-то еще, если даже. Как 7^6 = 1, потому что 7 = 0b0111
Это правильное направление решения проблем для этого? Я предполагаю, что моя проблема проистекает из первой операции, в частности (x + ~ 1), потому что она будет переполнять определенные 2 числа дополнения. Спасибо
Код:
int bitParity(int x) {
int first = x ^ (x + ~1);
int second = first ^ 1; // if first XOR gave 1 you'll return 0 here
int result = !!second;
return result;
}
3 ответа
Я бы использовал фактический подсчет, а не хаки на уровне битов, которые используют представление чисел, которые будут и чувствовать себя безопаснее, и будут более чистыми и легкими для понимания. Возможно, медленнее, конечно, но это довольно неплохой компромисс, особенно когда никто ничего не знает об ожидаемых результатах.
Для этого просто напишите код для подсчета числа в 1 бит, наиболее простое решение обычно сводится к циклу.
ОБНОВЛЕНИЕ: Учитывая (странные и раздражающие) ограничения, мой ответ, вероятно, заключался бы в том, чтобы развернуть цикл, приведенный в "наивном" решении на странице битхэков. Это было бы не красиво, но тогда я мог бы сделать что-нибудь полезное.:)
Ваша функция четности на самом деле не работает, насколько я могу судить - кажется, она дает правильный ответ примерно половину времени, что примерно так же хорошо, как возвращение случайного результата (или даже просто возвращение 0 или 1 все время),
Есть несколько хаков на уровне битов, которые действительно работают: http://graphics.stanford.edu/~seander/bithacks.html - вы, вероятно, захотите взглянуть на последний из них: http://graphics.stanford.edu/~seander/bithacks.html
Битовая четность может быть сделана так:
#include <stdio.h>
int parity(unsigned int x) {
int parity=0;
while (x > 0) {
parity = (parity + (x & 1)) % 2;
x >>= 1;
}
}
int main(int argc, char *argv[]) {
unsigned int i;
for (i = 0; i < 256; i++) {
printf("%d\t%s\n", i, parity(i)?"odd":"even");
}
}