14

I have two floating point number a and b. I want to check if they have different signs. The easy way is to see

bool b = a * b < 0;

But the two numbers are very small and a * b might be underflow. Any other simple way to check it?

Anyone thinking it is a duplicate question please give me an answer that exactly matches the condition a * b < 0. Note here the sign of 0 is undefined in my question.

user1899020
  • 13,167
  • 21
  • 79
  • 154
  • 4
    c++11 has [signbit](http://en.cppreference.com/w/cpp/numeric/math/signbit). So, something `signbit(a) == signbit(b)` will be true with both have the same sign. – wendelbsilva Dec 01 '15 at 22:00
  • fwiw, vs2012 doesn't seem to have signbit. 2013 does, though. can't you just multiply one number with a large number, like 1e20f? to ensure that the compiler doesn't reorder it, you can make a noinline function no_reorder that simply returns its argument, and then use no_reorder(a*1e20f)*b. or just cast one number to a double (if it isn't yet) – Anton Knyazyev Dec 02 '15 at 12:00

2 Answers2

9

You could use std::signbit as follows:

bool c = std::signbit(a) == std::signbit(b);

LIVE DEMO

Another way is to use std::copysign as follows:

bool c = std::copysign(a,b) == a;
101010
  • 41,839
  • 11
  • 94
  • 168
  • not exact to check a*b < 0. a and b can be 0 also. Check (1) a = 1, b = 0 (2) a = -1, b = 0 Both should be false. – user1899020 Dec 01 '15 at 22:13
  • @user1899020 If I got your question right, both `signbit` and `copysign` detect the sign bit of zeroes, infinities, and NaNs. – 101010 Dec 01 '15 at 22:15
  • @user1899020 a and b should be false as side effect of your "fast check" but does not mean it should be false for different signs – Slava Dec 01 '15 at 22:31
  • Two follow-up questions: 1. How does performance compare with OP multiplication-based comparison? 2. How to deal with +0 versus -0 having different sign despite being equal (and therefore "having the same everything, including the sign" for the purpose of most applications)? – Michael Dec 01 '15 at 23:07
2

Another solution is:

bool c = ((0 > a) == (0 > b));

Stamen Rakov
  • 456
  • 4
  • 10