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

时间:2020-03-05 18:54:31  来源:igfitidea点击:

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

解决方案

回答

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

假设非零等。

回答

就在我的头顶上...

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

回答

如果(a * b <0)符号不同,则符号相同(或者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));

如果(same_sign)...
别的 ...

回答

作为技术说明,即使在现代体系结构上,按比特排列的解决方案也将比乘法有效得多。我们只保存了大约3个周期,但是我们知道他们对"节省一分钱"的看法...

回答

(a ^ b) >= 0

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

回答

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

几乎100%的时间里,整数都会被存储为二进制补码,但是对系统内部进行假设并不是一个好习惯,除非我们使用的数据类型可以确保特定的存储格式。

用二的称赞,我们可以仅检查整数的最后一位(最左端)以确定它是否为负,因此我们可以仅比较这两位。但这意味着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:

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

回答

假设32位

如果((((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。

不假设二进制补码算术:

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

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

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