检查两个整数是否有相同符号的最简单方法是什么?有没有什么简短的按位技巧可以做到这一点?
如果(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)的答案是不好的,因为溢出
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);
它还支持其他基本类型(double、 float、 char等)。
double
float
char
#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"); } }