Reputation: 391
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
Reputation: 2603
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