rolika
rolika

Reputation: 391

Same sign of two integers

Please have a look at my code:

#include <stdio.h>
#include <stdbool.h>

void checksign(int, int);
bool samesign(int, int);

int main() {
    printf("Check same sign\n\n");

    int a = 27952, b = -68643, c = 0;

    checksign(a, a);
    checksign(a, b);
    checksign(a, c);
    checksign(b, b);
    checksign(b, c);
    checksign(c, c);

    return 0;
}

void checksign(int a, int b) {
    printf("%d and %d have ", a, b);
    if (!samesign(a, b)) {
        printf("not ");
    }
    printf("the same sign.\n");
}

bool samesign(int a, int b) {
    return (a | 0) == (b | 0);
}

I read the related topics here, which all showed reasonable solutions. I really can't understand why/how my samesign function works (at least for me, on a 64-bit Linux, compiled with GCC 7.3.0). Any help or insight is appreciated.

Upvotes: 1

Views: 192

Answers (1)

Your original code is completely wrong, as a | 0 == a for all a, and so (a|0) == (b|0) is equivalent to a == b.

For signed a, b, return false if they have opposing signs. Please note that 0 is considered to have a positive sign, even though -0 == 0. A naive implentation is provided below.

bool samesign(int a, int b) {
    if ((a < 0) && (b >= 0))
        return false;
    if ((a >= 0) && (b < 0))
        return false;
    return true;
}

However... There is a more clever and efficient solution using just one line, using bit manipulation and just thinking about the sign bit (based on two's complement numbers):

bool samesign(int a, int b) {
    /* Sign bit of XOR is 1 if only one of a or b is negative. */
    /* That means, signed a XOR b is negative if they have opposing signs. */
    return (signed int)(a ^ b) >= 0;
}

Your expected results should be:

27952 and 27952 have the same sign.
27952 and -68643 have not the same sign.
27952 and 0 have the same sign.
-68643 and -68643 have the same sign.
-68643 and 0 have the same sign. 
0 and 0 have the same sign.    

Upvotes: 2

Related Questions