与自身异或一个32位整数

时间:2016-10-20 01:54:06

标签: c bitwise-operators

我坚持用它本身对一个32位整数进行异或。我应该对整数的4个8位部分进行异或。我理解它是如何工作的,但是如果不将整数存储在任何地方,我就不知道如何做到这一点。

我已经考虑过了,我正在考虑使用二进制左移和右移操作符将32位整数分成4个部分来对它们进行异或。例如,如果我使用8位整数,我会做这样的事情:

int a = <some integer here>
(a << 4) ^ (a >> 4)

到目前为止,它并没有像我认为的那样工作。

这是我的代码的一部分:

else if (choice == 2) {
    int bits = 8;

    printf("Enter an integer for checksum calculation: ");
    scanf("%d", &in);
    printf("Integer: %d, ", in);

    int x = in, i;
    int mask = 1 << sizeof(int) * bits - 1;

    printf("Bit representation: ");

    for (i = 1; i <= sizeof(int) * bits; i++) {   
        if (x & mask)
            putchar('1');
        else
            putchar('0');

        x <<= 1;
        if (! (i % 8)) {
            putchar(' ');
        }
    }
    printf("\n");

}

以下是输出的示例:

    What type of display do you want? 
    Enter 1 for character parity, 2 for integer checksum: 2 
    Enter an integer for checksum calculation:  1024 
    Integer: 1024, Bit representation: 00000000 00000000 00000100 00000000
    Checksum of the number is: 4, Bit representation: 00000100     

2 个答案:

答案 0 :(得分:1)

要累加8位值的XOR,只需移动并对值的每个部分进行异或。从概念上讲,这是:

uint32_t checksum = ( (a >> 24) ^ (a >> 16) ^ (a >> 8) ^ a ) & 0xff;

但是,由于XOR可以按任何顺序完成,因此您可以使用较少的操作执行相同的操作:

uint32_t checksum = (a >> 16) ^ a;
checksum = ((checksum >> 8) ^ checksum) & 0xff;

如果您在许多值上执行此操作,则可以通过仅在最后浓缩值来扩展此想法。这与使用SIMD等技术在较大寄存器中完成并行交换操作的方式非常相似(实际上,具有SIMD支持的编译器应该能够优化以下代码以使其更快):

uint32_t simple_checksum( uint32_t *v, size_t count )
{
    uint32_t checksum = 0;
    uint32_t *end = v + count;
    for( ; v != end; v++ )
    {
        checksum ^= *v;            /* accumulate XOR of each 32-bit value     */
    }
    checksum ^= (checksum >> 16);  /* XOR high and low words into low word    */
    checksum ^= (checksum >> 8 );  /* XOR each byte of low word into low byte */
    return checksum & 0xff;        /* everything from bits 8-31 is rubbish    */
}

答案 1 :(得分:-1)

通常,对数字本身进行异或运算应该为您提供值0,这样您就可以轻松地将变量设置为0。

0100101 ^ 0100101 = 0

这是卡诺图的异或运算结果,当两个位均为1或都为0时提供0。