【问题标题】:calculate parity bit from string in c从c中的字符串计算奇偶校验位
【发布时间】:2015-06-05 09:42:18
【问题描述】:

我正在尝试使用以下代码计算字符串中的奇偶校验位,我首先计算字符串的 parityByte,然后计算 该字节的奇偶校验位,来自我收集的这些函数 应该做的伎俩,但我现在不太确定,我使用它们的程序失败了,如果是因为这些,或者我应该看看其他地方,我想现在。

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

【问题讨论】:

  • 使用unsigned char,而不是char。如果您右移(有符号的)char,则符号位将被保留。这会破坏您的奇偶校验计算。此外,x ^= x &gt;&gt; 8; 行是不必要的; x 只有 8 位。
  • 你能举一个输入失败的例子吗?我在这里没有发现任何问题(即使char 是有符号且为负的,那无用的x ^= x &gt;&gt; 8 步骤也无济于事——翻转所有位不会改变奇偶性)

标签: c bitwise-operators parity


【解决方案1】:

作为@squeamish ossifrage cmets:使用unsigned char 进行计算。由于char 可能有符号,因此右移可能会复制符号位。

此外,与char 相比,返回值int 的代码通常运行得最好。建议使用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);
}

将结果反转为奇校验。

【讨论】:

  • 看起来有一个; 应该是{。 @987654331 结束@
  • @David C. Rankin 对,你是
  • 如果我没记错的话,你可能还打算在calcOddParityBit:p中返回par % 2
  • @David C. Rankin 对,你是 2 岁
  • 这可能是个问题,但函数名称 calcOddParityBit 并没有计算 OddParityBit。恰恰相反,它正在计算`EvenParityBit。对于odd 奇偶校验,如果par 中有even1's 数量,则OddParityBit = 1 否则OddParityBit = 0。试试calcOddParityBit 换成10 (1010)11 (1011)。对于10,它返回0,对于11,它返回1。 (even 奇偶校验位):p
【解决方案2】:

你的功能:

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”填充移位的位这一事实与此解决方案无关(其中来源于你的)

尽管如果符号没有任何实际用途,最好不要将数字与符号一起使用,并且您将数字视为无符号数。

【讨论】:

  • 为什么是负数?
【解决方案3】:

Bit Twiddling Hacks的帮助下

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

这是 5 次操作对 7 次(在接受 @squeamish ossifrage 的好建议之后)。

【讨论】:

  • 现在您必须将v 更改为x :p 此外,它仅计算even 奇偶校验位。 (例如,奇数个 1's 奇偶校验位是 1 偶校验)odd 奇偶校验则相反。
【解决方案4】:

你必须记住:

1) 'x >> a' for(int i = 0; i >',则会在有符号类型中复制第一位,即 whitch == 1;

2) 运算符 '>>' 和 '

(错误示例:unsigned char y = (x > 2; for reset (in 0) 两个第一位)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-25
    • 2017-06-22
    • 1970-01-01
    • 2015-06-29
    • 2015-01-18
    • 2013-03-13
    • 2017-03-01
    • 2011-05-27
    相关资源
    最近更新 更多