简体   繁体   中英

Different bits of two given integers

Hey so I have been asked to get the number of different bits between two integers. I have written the code below which seem to work but only for positive numbers. I would love to know what am I doing wrong.

printf("Enter 2 numbers:\n");
        scanf("%d %d", &num1, &num2);
        xor_num = num1 ^ num2;
        while (xor_num != 0) {
            if (xor_num & 1) {
                xor_num = xor_num >> 1;
                bits_on += 1;
            }
            else
                xor_num = xor_num >> 1;
        }
        printf("There are %d diffrent bits\n", bits_on);

Shifting bits on a negative integer has implementation-defined behavior. In your case the sign bit (the most significant bit) is most likely not shifted so the variable xor_num never approaches zero and the loop is infinite. Instead you need to work on an unsigned integer. When you use the scanf function you also need to make sure that the input is valid. It is also a good idea to break out the code which calculates the number of bits into a separate function. Here is one way to do it:

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

int BitCount(int x)
{
    int result = 0;
    unsigned int y = x;
    
    while (y != 0) {
        result += (y & 1);
        y >>= 1;
    }
    return result;
}


int main(void)
{
    int n, x, y;

    printf("Enter 2 numbers:\n");
    n = scanf("%d %d", &x, &y);
    if (n == 2) {
        printf("There are %d diffrent bits\n", BitCount(x ^ y));
    } else {
        fprintf(stderr, "wrong input\n");
        exit(EXIT_FAILURE);
    }
    return 0;
}

When shifting negative values right, it is common for C implementations to copy the sign bit and leave it unchanged, rather than zeroing it. For example, where the four unsigned bits 1000 would be shifted to 0100 and then 0010 0001 , and 0000 , the four bits with a leading sign bit 1000 would be shifted to 1100 , 1110 , and then 1111 . (The C standard leaves it to the implementation to define this behavior, per C 2018 6.5.7 5.) In this case, when xor_num is negative, xor_num >> 1 leaves the sign bit set, so it never becomes non-negative.

The easiest way to deal with this, presuming you are using int types, is to use unsigned xor_num = num1 ^ num2; . If your C implementation uses two's complement do, which all regular implementations today do, the conversion from signed int to unsigned int will produce the same bits in xor_num but the shift with xor_num >> 1 will be a logical shift, which zeros the sign bit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM