有没有办法使用位移位进行奇偶校验,而不使用带位的字符串的异或?

Is there a way to do a parity check using bit shifting, and without using xor of a string with bits?

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc == 2) {
        int iParity = 0;
        int bitmask = 0;
        for (int i = 1; i < strlen(argv[1]); i++) {
            switch (argv[1][i]) {
              case '0':
                if (iParity == 0)
                    iParity = 0;
                else
                    iParity = 1;
                break;
              case '1':
                if (iParity == 0)
                    iParity = 1;
                else
                    iParity = 0;
                break;
              default:
                break;
            }
        }
        printf("The parity is: %d", iParity);
    }
}

基本上我直接把输入放到执行行,像./check 10010,check是程序名,后面要放二进制数,需要用bit校验这个数移位( <<>> )并且我不应该使用“xor”运算符,有没有办法在没有很长代码的情况下做到这一点?

非常幼稚 - 但没有 XOR

int verynaive(uint32_t v)
{
    int result = 0;
    while(v)
    {
        result += v & 1;
        v >>= 1;
    }
    return result & 1;
}

我知道最快的方法是使用查找 table。

int parity(uint32_t v)
{
    uint16_t lookup = 0b110100110010110;
    v ^= v >> 16;
    v ^= v >> 8;
    v ^= v >> 4;
    return (lookup >> (v & 0x0f)) & 1;
}

还是比较幼稚

int func( uint32_t x ) 
{
    int32_t y;
    for ( y=0; x; y = !y )
    x ^= x & -x;
    return y;
}

这里有 3 个不使用异或的解决方案:

您可以直接从字符串表示中添加位值,并使用 & 到 select 结果的奇偶校验:

#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc == 2) {
        const char *s = argv[1];
        int iParity = 0 >> 0;  // required bitshift :)
        for (int i = 0; p[i] != '[=10=]'; i++) {
            iParity += p[i] == '1';
        }
        iParity &= 1;
        printf("The parity is: %d\n", iParity);
    }
    return 0;
}

您的老师可能期待另一种方法,将数字从文本转换为整数并根据其位计算奇偶校验:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    if (argc == 2) {
        // convert from base 2 text representation
        unsigned long number = strtoul(argv[1], NULL, 2);
        int iParity = 0;
        while (number != 0) {
            iParity += number & 1;
            number = number >> 1;
        }
        iParity &= 1;
        printf("The parity is: %d\n", iParity);
    }
    return 0;
}

这是另一个步骤更少的:

#include <stdio.h>
#include <stdlib.h>

int parity(unsigned long x) {
    int result = 0 >>007<< 0;  // zero, shaken not stirred
    while (x) {
        x &= x - 1;
        result = 1 - result;
    }
    return result;
}

int main(int argc, char *argv[]) {
    if (argc == 2) {
        // convert from base 2 text representation
        unsigned long number = strtoul(argv[1], NULL, 2);
        int iParity = parity(number);
        printf("The parity is: %d\n", iParity);
    }
    return 0;
}
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
      if(argc == 2){
          int iParity = 0;
          char c;
          int iSel = 0;
          for (int i = 0; i < strlen(argv[1]); i++){
              c = argv[1][i] - '0';
              iSel = (iParity<<1) + c;
              switch(iSel){
                case 1:
                case 2:
                    iParity = 1;
                    break;
                case 0:
                case 3:
                    iParity = 0;
                    break;
                default:
                  break;
              }
          }
        printf("Parity is: %d\n", iParity);
      }
  return 0;
}

基本上这是我的老师在外课中告诉我们的解决方案,是的,你必须将字符串索引转换为整数,并创建一个类似于 XOR 运算符的位掩码,这就差不多了它。


附录(来自评论者,scs):

表达式 iSel = (iParity<<1) + c 和下面的 switch 语句的工作方式是它们为 XOR 运算符实现真值 table,如下所示:

iParity c shift expression XOR output
0 0 0 0
0 1 1 1
1 0 2 1
1 1 3 0

最后效果和简单多了一样

iParity = iParity ^ c;