2015-03-31 7 views
0

Я пытаюсь вычислить бит четности в строке, используя следующий код, я сначала вычислил бит четности для строки, а затем вычислил parityBit для этого байта, из чего я собрал эти функции должен сделать трюк, но я прямо сейчас не уверен, программа, в которой я их использую, не работает, и я бы хотел, если это из-за этого или если я должен посмотреть какое-то другое место.вычислить бит четности из строки в c

char calculateParity(char *payload, int size){ 
    char r = 0; 
    int i; 
    for(i = 0; i < size; i++){ 
     r ^= payload[i]; 
    } 
    return calcParityBit(r); 
} 

char calcParityBit(char x){ 
    x ^= x >> 8; 
    x ^= x >> 4; 
    x ^= x >> 2; 
    x ^= x >> 1; 
    return x & 1; 
} 
+1

Использование 'без знака char', а не' char'. Если вы смещаете знак (подписанный) 'char', тогда бит знака сохраняется. Это разрушает ваш анализ паритета. Кроме того, строка 'x^= x >> 8;' не нужна; 'x' имеет только 8 бит. –

+0

Можете ли вы привести пример ввода, который не удается? Я не вижу здесь ничего плохого (этот бесполезный шаг 'x^= x >> 8' ничего не делает, даже если' char' подписан и отрицателен - перелистывание всех битов не изменяет четность). – harold

ответ

0

Как @squeamish ossifrage комментарии: используйте unsigned char для расчета. Поскольку char могут быть подписаны, правое смещение может реплицировать бит знака.

Далее, код обычно лучше всего работает с возвратным значением int по сравнению с char. Рекомендовать использовать возвращаемое значение int или даже просто bool.

// Find parity (of any width up to the width of an unsigned) 
int calcEvenParityBit(unsigned par, unsigned width) { 
    while (width > 1) { 
    par ^= par >> (width/2); 
    width -= width/2; 
    } 

    // Only return Least Significant Bit 
    return par % 2; 
} 

int calculateEvenParity(char *payload, int size) { 
    unsigned char r = 0; 
    int i; 
    for(i = 0; i < size; i++) { 
    r ^= payload[i]; 
    } 
    return calcEvenParityBit(r, CHAR_BIT); 
} 

Инвертировать результат для нечетной четности.

+0

Похоже, существует ';' где '' '' должен быть. Конец 'int calcOddParityBit (беззнаковый пар, беззнаковая ширина);' –

+0

@David C.Ранкин Справа вы – chux

+0

Если я не ошибаюсь, возможно, вы также хотели бы вернуть 'par% 2' в' calcOddParityBit'': p' –

-1

Ваша функция:

char calcParityBit(char x){ 
    x ^= x >> 8; 
    x ^= x >> 4; 
    x ^= x >> 2; 
    x ^= x >> 1; 
    return x & 1; 
} 

вычисляет четность только три бита вашего байта. Для вычисления четности всего числа 8 бит, вы можете сделать что-то вроде этого:

char calcParityBit(char x){ 
    return ((x>>7)^
      (x>>6)^
      (x>>5)^
      (x>>4)^
      (x>>3)^
      (x>>2)^
      (x>>1)^
      (x)) & 1; 
} 

Как вы придерживаться наименьшего значащего бита, тот факт, что ваш аргумент подписан и сдвиг вправо операция может заполнить сдвинутые биты с «1», если самый значащий бит был «1», не имеет значения для этого решения (которое получено из вашего)

Хотя это хорошая практика, чтобы не использовать номер со знаком, если знак не используется, и вы обрабатываете число как неподписанное.

+0

И почему негатив? –

0

С помощью Bit Twiddling Hacks

char calcParityBit (unsigned char v) 
{ 
    return (0x6996u >> ((v^(v >> 4)) & 0xf)) & 1; 
} 

Это 5 операций против 7 (после приема @squeamish ossifrage «s хороший совет).

+0

Теперь вам нужно будет изменить 'v' на' x'': p' Также вычисляется только бит четности для четности 'even'. (например, нечетное число бит четности '1 'равно' 1' для четной четности). Противоположное значение имеет значение «четность». –

+0

@ Давид К. Ранкин, Спасибо за проверку кода! –

0

Вы должны помнить:

1) 'х >> а' то же самое для (INT I = 0; я < а, я ++) х/= 2; , потому что, если вы используете оператор '>>' для типа SIGNED, вы дублируете первый бит, whitch == 1 в подписанных типах;

2) operator '>>' и '< <' возвращает значение unsigned int;

(пример ошибки: символ без знака у = (х < < 2) >> 2; для сброса (в 0) двух первых битов)

 Смежные вопросы

  • Нет связанных вопросов^_^