检查两个整数是否有相同符号的最简单方法是什么?是否有任何简短的按位技巧?
答案 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);
它还支持其他基本类型(double
,float
,char
等。
答案 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");
}
}