判断两个整数是否同号的最简单方法是什么?是否有一种简短的按位运算技巧可以实现此功能?
判断两个整数是否同号的最简单方法是什么?是否有一种简短的按位运算技巧可以实现此功能?
有什么问题
return ((x<0) == (y<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);
}
注意:由于我们使用异或运算,当符号相同时,我们希望左操作数和右操作数不相同,因此需要对零进行不同的检查。(a ^ b) >= 0
如果符号相同,则计算结果为1,否则为0。
对于任何位运算技巧来确定整数的符号,我会持谨慎态度,因为这会让你假设那些数字是如何在系统内部表示的。
几乎100%的情况下,整数将被存储为二进制补码格式,但是除非你使用了一种保证特定存储格式的数据类型,否则假设系统内部结构不是一个好习惯。
在二进制补码中,您可以仅检查整数中最后(最左)位以确定它是否为负数,因此您可以比较这两个位。这意味着0将与正数具有相同的符号,这与大多数语言中实现的符号函数不一致。
个人而言,我建议使用所选语言的符号函数。这样的计算不太可能导致任何性能问题。
bool same = ((x ^ y) >> 31) != 1;
bool same = !((x ^ y) >> 31);
& >>
能工作呢? - MD XF我不确定“位运算技巧”和“最简单”是否是同义词。我看到很多答案都假定了有符号的32位整数(虽然要求无符号可能有些愚蠢);我不确定它们是否适用于浮点数。
似乎“最简单”的检查方法是比较两个值与0的大小关系;这在类型可以进行比较的情况下是非常普通的:
bool compare(T left, T right)
{
return (left < 0) == (right < 0);
}
(integer1 * integer2) > 0
当两个整数同号时,它们的乘积总是正数。
如果您想无论如何都将0视为相同符号,则可以将其更改为 >= 0。
假设使用二进制补码算术(http://en.wikipedia.org/wiki/Two_complement):
inline bool same_sign(int x, int y) {
return (x^y) >= 0;
}
这可以只需要两个指令,在优化后的现代处理器上不到1纳秒的时间。
不假设二进制补码算术:
inline bool same_sign(int x, int y) {
return (x<0) == (y<0);
}
这可能需要额外的一到两个指令并且需要更长的时间。
使用乘法是一个不好的想法,因为它容易溢出。