Simplest way to check if two integers have same sign?

前端 未结 18 2505
礼貌的吻别
礼貌的吻别 2020-12-04 13:53

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

相关标签:
18条回答
  • 2020-12-04 14:41

    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.

    0 讨论(0)
  • 2020-12-04 14:41

    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.

    0 讨论(0)
  • 2020-12-04 14:42

    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 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.

    0 讨论(0)
  • 2020-12-04 14:42

    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));
    }
    
    0 讨论(0)
  • 2020-12-04 14:43

    (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.

    0 讨论(0)
  • 2020-12-04 14:44

    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.

    0 讨论(0)
提交回复
热议问题