检查两个整数是否有相同符号的最简单方法?

时间:2008-09-15 20:57:04

标签: integer bit-manipulation sign

检查两个整数是否有相同符号的最简单方法是什么?是否有任何简短的按位技巧?

19 个答案:

答案 0 :(得分:202)

有什么问题
return ((x<0) == (y<0));  

答案 1 :(得分:46)

这是一个在C / C ++中工作的版本,它不依赖于整数大小或有溢出问题(即x * y&gt; = 0不起作用)

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

当然,你可以嘲笑和模板:

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

注意:由于我们使用exclusive或者,我们希望LHS和RHS在符号相同时不同,因此不同的检查为零。

答案 2 :(得分:23)

(a ^ b) >= 0
如果符号相同,

将评估为1,否则为0。

答案 3 :(得分:12)

我会对确定整数符号的任何按位技巧保持警惕,因为那时你必须假设这些数字是如何在内部表示的。

几乎100%的时间,整数将存储为two's compliment,但除非您使用的是保证特定存储格式的数据类型,否则对系统内部进行假设并不是一种好习惯。

在两个人的赞美中,您可以检查整数中的最后一个(最左侧)位以确定它是否为负数,因此您可以仅比较这两个位。这意味着0将具有与正数相同的符号,这与大多数语言中实现的符号函数不一致。

就个人而言,我只使用您所选语言的符号功能。这样的计算不太可能出现性能问题。

答案 4 :(得分:6)

假设32位整数:

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

稍微简洁一点:

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

答案 5 :(得分:5)

我不确定我会认为“按位技巧”和“最简单”是同义词。我看到很多答案都假定有符号的32位整数(虽然 对于要求无符号来说是愚蠢的);我不确定它们是否适用于浮点值。

似乎“最简单”的检查是比较两个值与0的比较;假设可以比较类型,这是非常通用的:

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

如果迹象相反,你会得到假的。如果迹象相同,你就会成真。

答案 6 :(得分:4)

假设二进制补码算术(http://en.wikipedia.org/wiki/Two_complement):

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

在具有优化功能的现代处理器上,这可能只需要两条指令,少于1ns。

不假设二进制补码算法:

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

这可能需要一两条额外的说明,并且需要更长时间。

使用乘法是一个坏主意,因为它很容易溢出。

答案 7 :(得分:4)

(整数1 *整数2)> 0

因为当两个整数共享一个符号时,乘法的结果将始终为正。

如果您想将0视为相同的符号,也可以将其设为&gt; = 0.

答案 8 :(得分:3)

if(x * y)&gt; 0 ...

假设非零等等。

答案 9 :(得分:2)

作为一个技术说明,即使在现代架构上,比特冗余的解决方案也会比乘法更有效。你节省的时间只有3个左右,但你知道他们对“便士保存”的看法......

答案 10 :(得分:1)

就在我头顶......

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

答案 11 :(得分:1)

无分支C版:

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

整数类型的C ++模板:

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

答案 12 :(得分:1)

假设32位

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

...由于溢出

,答案if(x*y>0)很糟糕

答案 13 :(得分:1)

对于具有二进制补码算术的任何大小的int:

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

答案 14 :(得分:0)

int same_sign =!((x&gt;&gt; 31)^(y&gt;&gt; 31));

if(same_sign)... 别的......

答案 15 :(得分:0)

回想我的大学时代,在大多数机器表示中,当数字为负数时,它不是整数的最左边的一个1,而当它是正数时,它不是0?

我认为这是依赖于机器的。

答案 16 :(得分:0)

如果(a * b <0)符号不同,则其他符号相同(或者a或b为零)

答案 17 :(得分:0)

使用std::signbit的更好方法如下:

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

它还支持其他基本类型(doublefloatchar等。

答案 18 :(得分:0)

#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");
    }
}