20

I'm searching for an efficient way to check if two numbers have the same sign.

Basically I'm searching for a more elegant way than this:

var n1 = 1;
var n2 = -1;

( (n1 > 0 && n2 > 0) || (n1<0 && n2 < 0) )? console.log("equal sign"):console.log("different sign");

A solution with bitwise operators would be fine too.

antyrat
  • 27,479
  • 9
  • 75
  • 76
Christoph
  • 50,121
  • 21
  • 99
  • 128
  • 1
    It's not JavaScript, but I guess all of these work as well: [Simplest way to check if two integers have same sign?](http://stackoverflow.com/questions/66882/simplest-way-to-check-if-two-integers-have-same-sign). – Felix Kling Apr 24 '12 at 12:52
  • @FelixKling Yeah, i read this question but stopped at the accepted answer, which i wasn't satisfied with;) – Christoph Apr 24 '12 at 12:55
  • 3
    Well, the [next answer](http://stackoverflow.com/a/67498/218196) is pretty cool imo: `return ((x<0) ==(y<0));`. – Felix Kling Apr 24 '12 at 12:57
  • @FelixKling thats true, another case for "Don't stop reading after accepted answer" – Christoph Apr 24 '12 at 12:59

6 Answers6

57

You can multiply them together; if they have the same sign, the result will be positive.

bool sameSign = (n1 * n2) > 0
Jason Hall
  • 20,632
  • 4
  • 50
  • 57
  • 20
    What if `n1` and `n2` are both positive integers but multiplying them causes an integer overlow? – Thorsten Dittmar Apr 24 '12 at 12:51
  • @ThorstenDittmar I was worried someone would point that out ;) -- in that case, http://stackoverflow.com/questions/66882/simplest-way-to-check-if-two-integers-have-same-sign – Jason Hall Apr 24 '12 at 12:53
  • @ThorstenDittmar this problem won't occur in my case, but nevertheless worth pointing this out. – Christoph Apr 24 '12 at 12:57
  • 5
    What if `n1` and `n2` are both zero? – Matthew Crumley Apr 24 '12 at 13:06
  • @Matthew: That's actually more tricky. In JavaScript there exists `+0` and `-0`... seems like bit operations are necessary here. Of course if you don't care to differ between these two zeros, a simple `n1 === n2` is sufficient... – Felix Kling Apr 24 '12 at 13:09
  • 1
    @ThorstenDittmar JavaScript will never cause integer overflow on Number type, since they are not "integers" at all. They are float, IEEE 754 float. – tsh May 31 '17 at 05:39
  • 1
    God knows why @ThorstenDittmar got so many upvotes. As tsh pointed out, JavaScript does not have integer overflows and underflows because JavaScript doesn't have integers (excluding BigNum, but those can't overflow either) – DavidsKanal Jul 14 '19 at 22:36
22

Fewer characters of code, but might underflow for very small numbers:

n1*n2 > 0 ? console.log("equal sign") : console.log("different sign or zero");

Note: As @tsh correctly mentioned, an overflow with an intermediate result of Infinity or -Infinity does work. But an underflow with an intermediate result of +0 or -0 will fail, because +0 is not bigger than 0.

or without underflow, but slightly larger:

(n1<0) == (n2<0) ? console.log("equal sign") : console.log("different sign");
user1346466
  • 630
  • 4
  • 11
11

Use bitwise xor

n1^n2 >= 0 ? console.log("equal sign") : console.log("different sign");
Christoph
  • 50,121
  • 21
  • 99
  • 128
william
  • 233
  • 1
  • 6
6

That based on how you define "same sign" for special values:

  • does NaN, NaN have the same sign?

If your answer is "No", the answer is:

Math.sign(a) === Math.sign(b)

If your answer is "Yes", the answer is:

Object.is(Math.sign(a) + 0, Math.sign(b) + 0)
Christoph
  • 50,121
  • 21
  • 99
  • 128
tsh
  • 4,263
  • 5
  • 28
  • 47
  • Unfortunately, the correct answer would be "Yes" and "Yes", and thus this approach is not particularly useful (besides the fact, that it is not really practical to invoke the `Math` object for such a trivial task). – Christoph Jun 01 '17 at 14:28
  • @Christoph YY and NN had been added to the answer. – tsh Jun 02 '17 at 01:18
  • @Christoph I cannot understand why you do not want use methods in ES Spec. You do not need add dependency to any third party cods, and they should work better than most codes other people wrote. You may say this task is "trivial", but I did not find other answers handle these edge cases correctly. You may say "it is not my business for my specified question", but that should not be a "correct" answer to this question. – tsh Jun 02 '17 at 01:21
  • I removed the `+-0` part, since the spec clearly states, how to treat this case. I think you misunderstood my comment - I know that this is a native object, I just think, that it's "overkill" to use it, if there are simpler solutions (besides the fact, that I was looking for a short solution). Nonetheless, I gave you an upvote for your "outside-the-box" solution. – Christoph Jun 02 '17 at 14:22
1
n = n1*n2;
if(n>0){ same sign }
else { different sign }
sgowd
  • 2,242
  • 22
  • 29
-5

Maybe a regex should do the trick

function isNegative(num) { 
        if (num.match(/^-\d+$/)) {
            return true;
        } else {
            return false;
        }
   }


function isSameSign(num1, num2) { 
        var sameSign = false;  
        if (num1.match(/^-\d+$/) && num2.match(/^-\d+$/) ) {
                sameSign = true;
            } else if(!num2.match(/^-\d+$/) && !num2.match(/^-\d+$/)) {
                sameSign =true;
            }
        return sameSign;
       }
Sandeep Nair
  • 3,630
  • 3
  • 26
  • 38
  • This only returns whether one number is false. If you want to do that, you can just check `num > 0` -- to convert a string to a number first you can do `parseInt(num) > 0` – Jason Hall Apr 24 '12 at 13:31
  • Well it just requires a tweak. I have updated and given a second version to show, how the first function can be modified to achieve the requirement – Sandeep Nair Apr 24 '12 at 13:38
  • But you're still using a fragile regex instead of the built-in `parseInt` method. – Jason Hall Apr 24 '12 at 14:38
  • Even `return num1<0 && num2<0 || num1>=0 && num2>=0;` better and shorter – vp_arth May 30 '16 at 10:05