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

检查两个整数是否有相同符号的最简单方法是什么?有没有什么简短的按位技巧可以做到这一点?

51331 次浏览

如果(x * y) > 0..。

假设不是零什么的。

我一下子就想到了。

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

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

假设32位整数:

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

更简洁一点:

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

回想我的大学时代,在大多数机器表示中,整数最左边的位不是负数时的1,正数时的0吗?

不过,我想这相当依赖于机器。

(整数1 * 整数2) > 0

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

如果希望无论如何都将0视为相同的符号,也可以将其设置为 > = 0。

Int same _ sign = ! ((x > > 31) ^ (y > 31)) ;

如果(同一个符号) ..。 否则..。

作为一个技术说明,比特缠绕的解决方案将比乘法更有效,即使在现代架构上也是如此。虽然你只省了3个周期,但你知道他们怎么说“省了一分钱”..。

(a ^ b) >= 0

如果符号相同,则计算结果为1,否则为0。

我会提防任何确定整数符号的按位技巧,因为那样你就必须假设这些数字在内部是如何表示的。

几乎100% 的情况下,整数都会以 2号的赞美的形式存储,但是对系统的内部结构做出假设并不是一个好的做法,除非您使用的数据类型保证了特定的存储格式。

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

就我个人而言,我会用你选择的语言的符号函数。这样的计算不太可能出现任何性能问题。

下面是一个在 C/C + + 中运行的版本,它不依赖于整数大小,也不存在溢出问题(即 x * y > = 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);
}

注意: 由于我们使用独占或,我们希望 LHS 和 RHS 是不同的时,符号是相同的,从而不同的检查对零。

对于任意大小的 int,使用2的补数算法:

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

假设是32位

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

... if(x*y>0)的答案是不好的,因为溢出

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

似乎“最简单”的检查方法是比较两个值与0的比较情况; 假设类型可以进行比较,那么这种检查方法相当通用:

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

如果符号相反,你就得到假,如果符号相同,你就得到真。

怎么了

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

假设两个补足算术(http://en.wikipedia.org/wiki/Two_complement) :

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

在现代处理器上,通过优化,这可能只需要两条指令,而不到1ns。

不要假设2补充算术:

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

这可能需要一个或两个额外的指示,并需要一点时间。

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

无分支 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));
}

使用 Signbit的更好方法如下:

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

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

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