Вычислить бит четности из строки в c

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

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;
}

4 ответа

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

1) 'x >> a' то же самое для (int i = 0; i >' для типа SIGNED, вы дублируете первый бит, whitch == 1 в типах со знаком;

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

(Пример ошибки: unsigned char y = (x << 2) >> 2; для сброса (в 0) два первых бита)

С помощью Bit Twiddling Hacks

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

Это 5 операций против 7 (после получения хорошего совета squeamish ossifrage).

Как 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);
}

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

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

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", не имеет значения для этого решения (которое получается из ваш)

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

Другие вопросы по тегам