Как проверить, имеет ли значение четность битов или нечетность?
значение имеет четность, если оно имеет четное число 1 бит. Значение имеет нечетную четность, если оно имеет нечетное число 1 бит. Например, 0110
имеет четность и 1110
и нечетность.
Я должен вернуть 1
Если x
даже паритета.
int has_even_parity(unsigned int x) {
return
}
8 ответов
попробуй:
int has_even_parity(unsigned int x){
unsigned int count = 0, i, b = 1;
for(i = 0; i < 32; i++){
if( x & (b << i) ){count++;}
}
if( (count % 2) ){return 0;}
return 1;
}
valter
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return (~x) & 1;
предполагая, что вы знаете, что ints 32 бита.
давайте посмотрим, как это работает. Чтобы все было просто, давайте используем 8-битное целое число, для которого мы можем пропустить первые два shift/XORs. Давайте обозначим биты a через h. Если мы посмотрим на наш номер мы видим:
( a b c d e f g h )
первая операция x ^= x >> 4
(помните, что мы пропускаем первые две операции, так как в этом примере мы имеем дело только с 8-битным целым числом). Давайте напишем новые значения каждого бита, объединив буквы, которые XOR'D вместе (например,ab означает, что бит имеет значение a xor b).
( a b c d e f g h ) исключающее или ( 0 0 0 0 a b c d )
результат следующие биты:
( a b c d ae bf cg dh )
в следующей операцией является x ^= x >> 2
:
( a b c d ae bf cg dh ) исключающее или ( 0 0 a b c d ae bf )
результат следующие биты:
( a b ac bd АПФ bdf aceg bdfh )
обратите внимание, как мы начинаем накапливать все биты с правой стороны.
следующая операция x ^= x >> 1
:
( a b ac bd АПФ bdf aceg bdfh ) исключающее или ( 0 a b ac bd АПФ bdf aceg )
результат следующие биты:
( a ab abc abcd abcde abcdef abcdefgh abcdefgh )
мы накопили все биты в исходном слове, XOR'D вместе, в наименее значимом бит. Таким образом, этот бит теперь равен нулю, если и только если во входном слове было четное число 1 бит (четность). Тот же процесс работает на 32-разрядных целых чисел (но требует двух дополнительных изменений, которые мы пропустили в этой демонстрации).
последняя строка кода просто удаляет все, кроме наименее значимого бита (& 1
), а затем переворачивает его (~x
). Таким образом, результат равен 1, Если четность входного слова была четной или нулевой в противном случае.
следующий ответ был бесстыдно поднят прямо из бит Twiddling хаки Шон Эрон Андерсон, seander@cs.stanford.edu
вычислить четность слова с умножением
следующий метод вычисляет четность 32-разрядного значения только в 8 операциях >с помощью умножения.
unsigned int v; // 32-bit word
v ^= v >> 1;
v ^= v >> 2;
v = (v & 0x11111111U) * 0x11111111U;
return (v >> 28) & 1;
также для 64-бит, 8 операций по прежнему достаточно.
unsigned long long v; // 64-bit word
v ^= v >> 1;
v ^= v >> 2;
v = (v & 0x1111111111111111UL) * 0x1111111111111111UL;
return (v >> 60) & 1;
Эндрю Шапира придумал это и отправил мне на сентябрь. 2 2007,.
на GCC есть встроенная функция для этого:
встроенные функции:
int __builtin_parity (unsigned int x)
возвращает паритет
x
, т. е. число 1-бит в x по модулю 2.
т. е. эта функция ведет себя как has_odd_parity
. Инвертировать значение для has_even_parity
.
это гарантированно будет самой быстрой альтернативой на GCC. Конечно, его использование не является портативным как таковым, но вы можете использовать его в своей реализации, охраняемой макрос, например.
основная идея заключается в следующем. Снимите самый правый бит ' 1 ' с помощью x & ( x - 1 )
. Скажем, x = 13 (1101) и операция x & ( x - 1 )
is 1101 & 1100
что 1100, обратите внимание, что самый правый бит набора преобразуется в 0
.
теперь x
is 1100
. Операция x & ( x - 1 )
Я.е 1100 & 1011
is 1000
. Обратите внимание, что оригинал x
is 1101
и после двух операций x & (x - 1)
the x
is 1000
, i.e два бита набора удаляются после двух операций. Если после odd
количество операций,x
становится нулем, затем его нечетная четность, иначе его четная четность.
обобщить ответ @TypelA для любой архитектуры:
int has_even_parity(unsigned int x)
{
unsigned char shift=1;
while (shift < (sizeof(x)*8))
{
x ^= (x>>shift);
shift<<=1;
}
return !(x & 0x1);
}
int parity_check(unsigned x) {
int parity = 0;
while(x != 0) {
parity ^= x;
x >>= 1;
}
return (parity & 0x1);
}
Это довольно старый вопрос, но я отправляю это для тех, кто может использовать его в будущем.
Я не буду добавлять пример этого в c, так как уже есть достаточно хороших ответов.
в случае, если конечный результат должен быть фрагментом кода, который может работать (компилироваться) с программой на c, я предлагаю следующее:
.code
; bool CheckParity(size_t Result)
CheckParity PROC
mov rax, 0
add rcx, 0
jnp jmp_over
mov rax, 1
jmp_over:
ret
CheckParity ENDP
END
Это фрагмент кода, который я использую для проверки четности вычисленных результатов в 64-битной программе c, скомпилированной с помощью MSVC. Очевидно, что вы можете перенести его на 32bit или другие компиляторы.
это имеет преимущество быть гораздо быстрее, чем с помощью c, и он также использует функциональность процессоров.
в этом примере в качестве входного параметра используется параметр (переданный в соглашении вызова RCX - __fastcall). Он увеличивает его на 0, таким образом, устанавливая флаг четности процессоров, а затем устанавливая переменную (RAX) в 0 или 1, если флаг четности включен или нет.