C 如何检查值是否具有位的偶数奇偶校验或奇数奇偶校验?

C 如何检查值是否具有位的偶数奇偶校验或奇数奇偶校验?,c,bits,C,Bits,如果值具有偶数个1位,则该值具有偶数奇偶校验。如果值的奇数为1位,则该值具有奇数奇偶校验。例如,0110具有偶数奇偶校验,1110具有奇数奇偶校验 如果x具有奇偶校验,我必须返回1 int has_even_parity(unsigned int x) { return } 假设你知道整数是32位 让我们看看这是怎么回事。为了简单起见,让我们使用一个8位整数,我们可以跳过前两个移位/异或。让我们给位a到h贴上标签。如果我们查看我们的数字,我们会看到: (a b c d e f g

如果值具有偶数个1位,则该值具有偶数奇偶校验。如果值的奇数为1位,则该值具有奇数奇偶校验。例如,
0110
具有偶数奇偶校验,
1110
具有奇数奇偶校验

如果
x
具有奇偶校验,我必须返回
1

int has_even_parity(unsigned int x) {
    return 
}
假设你知道整数是32位


让我们看看这是怎么回事。为了简单起见,让我们使用一个8位整数,我们可以跳过前两个移位/异或。让我们给位a到h贴上标签。如果我们查看我们的数字,我们会看到:

(a b c d e f g h)


第一个操作是
x^=x>>4
(记住我们跳过了前两个操作,因为在本例中我们只处理8位整数)。让我们通过将异或字母组合在一起来写入每个位的新值(例如,ab表示该位的值为a或b)

(a b c d e f g h) 异或 (零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零零

结果是以下位:

(a、b、c、d、ae、bf、cg、dh)


下一个操作是
x^=x>>2

(a、b、c、d、ae、bf、cg、dh) 异或 (0 a b c d ae bf)

结果是以下位:

(a b ac bd ace bdf ace bdfh)

注意我们是如何开始累积右侧的所有位的


下一个操作是
x^=x>>1

(a b ac bd ace bdf ace bdfh) 异或 (0 a b ac bd ace bdf aceg)

结果是以下位:

(a ab abc abcd abcde abcdef abcdefg abcdefgh)


我们已将原始字中的所有位(XOR’d)累加在一起,在最低有效位。因此,当且仅当输入字中有偶数个1位(偶数奇偶校验)时,该位现在为零。同样的过程也适用于32位整数(但需要我们在本演示中跳过的两个额外移位)

最后一行代码只需去掉除最低有效位以外的所有位(
&1
),然后翻转它(
~x
)。如果输入字的奇偶校验为偶数,则结果为1,否则为零。

尝试:

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;
}
int具有偶数奇偶校验(无符号int x){
无符号整数计数=0,i,b=1;
对于(i=0;i<32;i++){

如果(x&(b的话),下面的答案是直接从

用乘法计算单词的奇偶性

以下方法仅在8次操作>中使用乘法计算32位值的奇偶校验

同样对于64位,8次操作仍然足够

安德鲁·沙皮拉(Andrew Shapira)提出了这个,并于2007年9月2日寄给我


主要思想是这样的。通过使用
x&(x-1)
取消设置最右边的“1”位。假设x=13(1101),并且
x&(x-1)
的操作是
1101&1100
即1100,注意最右边的设置位被转换为
0


现在
x
1100
x&(x-1)
的操作,即
1100&1011
1000
。请注意,原始
x
1101
并且在
x&(x-1)的两次操作之后
x
1000
,即两次操作后两个设置位被删除。如果在
奇数
次操作后,
x
变为零,那么它是奇数奇偶校验,否则它是偶数奇偶校验。

这是一个很老的问题,但我将为将来可能使用它的人发布这个问题

int has_even_parity(unsigned int x) {
    return 
}
因为已经有足够多的好答案了,所以我不会再添加一个用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
这是我用来检查用MSVC编译的64位c程序中计算结果奇偶性的一段代码。显然,您可以将其移植到32位或其他编译器

这具有比使用c快得多的优点,并且它还利用了CPU功能


本例所做的是将一个参数作为输入(在RCX-_fastcall调用约定中传递)。它将其递增0,从而设置CPU奇偶校验标志,然后如果奇偶校验标志是否打开,则将变量(RAX)设置为0或1。

概括@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具有偶数奇偶校验(无符号int x)
{
无符号字符移位=1;
而(班次<(尺寸(x)*8))
{
x^=(x>>移位);
shiftGCC对此有:

内置函数:
int\u内置奇偶校验(无符号int x)

返回
x
的奇偶校验,即x模2中的1位数

以及用于
无符号长
无符号长
的类似函数

也就是说,此函数的行为类似于
具有奇偶校验
。反转
具有偶偶校验
的值


这些应该是GCC上最快的替代方案。当然,它的使用本身是不可移植的,但您可以在实现中使用它,例如由宏保护。

这里有一个单行
\define
,它实现了
字符的技巧:

#define PARITY(x) ((~(x ^= (x ^= (x ^= x >> 4) >> 2) >> 1)) & 1) /* even parity */

int main()
{
    char x=3;
    printf("parity = %d\n", PARITY(x));
}
它的便携性非常好,并且易于修改以处理更大的字(16,32位)。另外,需要注意的是,使用
#define
可以加快代码的速度,每次函数调用都需要时间来推动堆栈和分配内存。代码大小不会受到影响,尤其是在代码中只实现了几次的情况下-函数调用可能会占用与XOR相同的目标代码


诚然,通过使用此函数的内联版本、
内联字符奇偶校验(char x){return parity(x);}
(GCC)或
uu内联字符奇偶校验(char x){return parity(x);}
(MSVC)可以获得相同的效率。假设您保持一行定义。

欢迎这样做。请阅读并回答如何提问。去阅读有关C中位移位的内容。@OldProgrammer需要这样做吗?我不清楚
.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
int has_even_parity(unsigned int x) 
{
    unsigned char shift=1;
    while (shift < (sizeof(x)*8))
    {
            x ^= (x>>shift);
            shift<<=1;
    }
    return !(x & 0x1);
}
#define PARITY(x) ((~(x ^= (x ^= (x ^= x >> 4) >> 2) >> 1)) & 1) /* even parity */

int main()
{
    char x=3;
    printf("parity = %d\n", PARITY(x));
}