Simplest way to check if two integers have same sign?

IntegerBit ManipulationSign

Integer Problem Overview


Which is the simplest way to check if two integers have same sign? Is there any short bitwise trick to do this?

Integer Solutions


Solution 1 - Integer

What's wrong with

return ((x<0) == (y<0));  

?

Solution 2 - Integer

Here is a version that works in C/C++ that doesn't rely on integer sizes or have the overflow problem (i.e. x*y>=0 doesn't work)

bool SameSign(int x, int y)
{
    return (x >= 0) ^ (y < 0);
}

Of course, you can geek out and template:

template <typename valueType>
bool SameSign(typename valueType x, typename valueType y)
{
    return (x >= 0) ^ (y < 0);
}

Note: Since we are using exclusive or, we want the LHS and the RHS to be different when the signs are the same, thus the different check against zero.

Solution 3 - Integer

(a ^ b) >= 0

will evaluate to 1 if the sign is the same, 0 otherwise.

Solution 4 - Integer

I would be wary of any bitwise tricks to determine the sign of integers, as then you have to make assumptions about how those numbers are represented internally.

Almost 100% of the time, integers will be stored as http://en.wikipedia.org/wiki/Twos_Compliment">two's compliment, but it's not good practice to make assumptions about the internals of a system unless you are using a datatype that guarentees a particular storage format.

In two's compliment, you can just check the last (left-most) bit in the integer to determine if it is negative, so you can compare just these two bits. This would mean that 0 would have the same sign as a positive number though, which is at odds with the sign function implemented in most languages.

Personally, I'd just use the sign function of your chosen language. It is unlikely that there would be any performance issues with a calculation such as this.

Solution 5 - Integer

Assuming 32 bit ints:

bool same = ((x ^ y) >> 31) != 1;

Slightly more terse:

bool same = !((x ^ y) >> 31);

Solution 6 - Integer

(integer1 * integer2) > 0

Because when two integers share a sign, the result of multiplication will always be positive.

You can also make it >= 0 if you want to treat 0 as being the same sign no matter what.

Solution 7 - Integer

I'm not really sure I'd consider "bitwise trick" and "simplest" to be synonymous. I see a lot of answers that are assuming signed 32-bit integers (though it would be silly to ask for unsigned); I'm not certain they'd apply to floating-point values.

It seems like the "simplest" check would be to compare how both values compare to 0; this is pretty generic assuming the types can be compared:

bool compare(T left, T right)
{
    return (left < 0) == (right < 0);
}

If the signs are opposite, you get false. If the signs are the same, you get true.

Solution 8 - Integer

Assuming twos complement arithmetic (http://en.wikipedia.org/wiki/Two_complement):

inline bool same_sign(int x, int y) {
    return (x^y) >= 0;
}

This can take as little as two instructions and less than 1ns on a modern processor with optimization.

Not assuming twos complement arithmetic:

inline bool same_sign(int x, int y) {
    return (x<0) == (y<0);
}

This may require one or two extra instructions and take a little longer.

Using multiplication is a bad idea because it is vulnerable to overflow.

Solution 9 - Integer

if (x * y) > 0...

assuming non-zero and such.

Solution 10 - Integer

As a technical note, bit-twiddly solutions are going to be much more efficient than multiplication, even on modern architectures. It's only about 3 cycles that you're saving, but you know what they say about a "penny saved"...

Solution 11 - Integer

Just off the top of my head...

int mask = 1 << 31;
(a & mask) ^ (b & mask) < 0;

Solution 12 - Integer

if (a*b < 0) sign is different, else sign is the same (or a or b is zero)

Solution 13 - Integer

For any size of int with two's complement arithmetic:

#define SIGNBIT (~((unsigned int)-1 >> 1))
if ((x & SIGNBIT) == (y & SIGNBIT))
    // signs are the same

Solution 14 - Integer

assuming 32 bit

if(((x^y) & 0x80000000) == 0)

... the answer if(x*y>0) is bad due to overflow

Solution 15 - Integer

branchless C version:

int sameSign(int a, int b) {
    return ~(a^b) & (1<<(sizeof(int)*8-1));
}

C++ template for integer types:

template <typename T> T sameSign(T a, T b) {
    return ~(a^b) & (1<<(sizeof(T)*8-1));
}

Solution 16 - Integer

Thinking back to my university days, in most machine representations, isn't the left-most bit of a integer a 1 when the number is negative, and 0 when it's positive?

I imagine this is rather machine-dependent, though.

Solution 17 - Integer

int same_sign = !( (x >> 31) ^ (y >> 31) );

if ( same_sign ) ... else ...

Solution 18 - Integer

Better way using std::signbit as follows:

std::signbit(firstNumber) == std::signbit(secondNumber);

It also support other basic types (double, float, char etc).

Solution 19 - Integer

#include<stdio.h>

int checksign(int a, int b)
{
 return (a ^ b); 
}

void  main()
{
    int a=-1, b = 0;

    if(checksign(a,b)<0)
    {
        printf("Integers have the opposite sign");
    }
    else
    {
        printf("Integers have the same sign");
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGerberView Question on Stackoverflow
Solution 1 - IntegerRikView Answer on Stackoverflow
Solution 2 - IntegerTorlackView Answer on Stackoverflow
Solution 3 - IntegerChris JobsonView Answer on Stackoverflow
Solution 4 - IntegerSpoonMeiserView Answer on Stackoverflow
Solution 5 - IntegerPatrickView Answer on Stackoverflow
Solution 6 - IntegerBenjamin AutinView Answer on Stackoverflow
Solution 7 - IntegerOwenPView Answer on Stackoverflow
Solution 8 - Integeruser10315View Answer on Stackoverflow
Solution 9 - IntegerYes - that Jake.View Answer on Stackoverflow
Solution 10 - IntegerDaniel SpiewakView Answer on Stackoverflow
Solution 11 - IntegerDaniel SpiewakView Answer on Stackoverflow
Solution 12 - IntegerdogfishView Answer on Stackoverflow
Solution 13 - IntegerMark RansomView Answer on Stackoverflow
Solution 14 - IntegerugasoftView Answer on Stackoverflow
Solution 15 - IntegerCAFxXView Answer on Stackoverflow
Solution 16 - IntegerDanaView Answer on Stackoverflow
Solution 17 - IntegerandrewView Answer on Stackoverflow
Solution 18 - Integerashiquzzaman33View Answer on Stackoverflow
Solution 19 - IntegerKrazzy4CodeView Answer on Stackoverflow