bitwise operators for finding less than in c

后端 未结 4 1438
离开以前
离开以前 2020-12-19 03:45

This is a homework assignment which requires me to come up with a function to determine if x < y, if it is I must return 1, using only bitwise o

相关标签:
4条回答
  • 2020-12-19 04:27

    I think it can be achived doing following:

    1. Xor both numbers, that will give you bits that differs
    2. Get the most significant bit that differs, as this one will make a difference
    3. Check if that most significant bit belongs to bigger value

    Code:

    int less(int x, int y) {
        //Get only diffed bits
        int msb = x ^ y;
        //Get first msb bit
        msb |= (msb >>  1);
        msb |= (msb >>  2);
        msb |= (msb >>  4);
        msb |= (msb >>  8);
        msb |= (msb >> 16);
        msb = msb - (msb >> 1);
        //check if msb belongs to y;
        return !((y & msb) ^ msb);
    }
    
    0 讨论(0)
  • 2020-12-19 04:40

    The idea of implementing subtraction is good.

    int sub = x + (~y+1);
    

    From here, you just need to check whether sub is negative, i.e. extract its sign bit. This is where the technical difficulty appears.

    Let's assume x and y are unsigned 32-bit integers. Then the result of subtraction can be represented by a signed 33-bit integer (check its minimum and maximum values to see that). That is, using the expression x + (~y+1) directly doesn't help, because it will overflow.

    What if x and y were 31-bit unsigned numbers? Then, x + (~y+1) can be represented by a 32-bit signed number, and its sign bit tells us whether x is smaller than y:

    answer(x, y) := ((x + (~y+1)) >> 31) & 1
    

    To convert x and y from 32 bits to 31 bits, separate their MSB (most significant bit) and all the other 31 bits into different variables:

    msb_x = (x >> 31) & 1;
    msb_y = (y >> 31) & 1;
    x_without_msb = x << 1 >> 1;
    y_without_msb = y << 1 >> 1;
    

    Then consider the 4 possible combinations of their MSB:

    if (msb_x == 0 && msb_y == 0)
        return answer(x_without_msb, y_without_msb);
    else if (msb_x == 1 && msb_y == 0)
        return 0; // x is greater than y
    else if (msb_x == 0 && msb_y == 1)
        return 1; // x is smaller than y
    else
        return answer(x_without_msb, y_without_msb);
    

    Converting all these if-statements to a single big ugly logical expression is "an exercise for the reader".

    0 讨论(0)
  • 2020-12-19 04:44

    In order to know if x < y, you can simply ask if x - y < 0.

    In other words, what is the sign of the result of x - y.

    Since you stated you are to assume 32 bit integers, following will provide the correct result:

    ((x - y) >> 31) & 0x1
    
    0 讨论(0)
  • 2020-12-19 04:47

    Here was my attempt (compiling results, x > y then 0, x < y then 1, x == y then 1):

    ((((x + ~y) >> 31) + 1))^1
    
    0 讨论(0)
提交回复
热议问题