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

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

19 回答 19

This answer is useful

227

有什么问题

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

?

于 2008-09-15T22:06:19.607 回答

This answer is useful

52

这是一个在 C/C++ 中工作的版本,它不依赖于整数大小或存在溢出问题(即 x*y>=0 不起作用)

bool SameSign(int x, int y)

{

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

}

当然,你可以geek out和template:

template

bool SameSign(typename valueType x, typename valueType y)

{

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

}

注意:由于我们使用异或,当符号相同时,我们希望 LHS 和 RHS 不同,因此对零进行不同的检查。

于 2008-09-15T21:12:14.310 回答

This answer is useful

34

(a ^ b) >= 0

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

于 2008-09-15T21:06:18.160 回答

This answer is useful

12

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

几乎 100% 的情况下,整数将作为二进制补码存储,但除非您使用保证特定存储格式的数据类型,否则对系统内部进行假设并不是一个好习惯。

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

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

于 2008-09-15T21:06:48.673 回答

This answer is useful

6

假设 32 位整数:

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

稍微简洁一点:

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

于 2008-09-15T21:01:24.273 回答

This answer is useful

5

(整数 1 * 整数 2) > 0

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

如果您无论如何都想将 0 视为相同的符号,也可以使其 >= 0。

于 2008-09-15T21:01:46.470 回答

This answer is useful

5

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

似乎“最简单”的检查是比较两个值与 0 的比较;假设可以比较类型,这是非常通用的:

bool compare(T left, T right)

{

return (left < 0) == (right < 0);

}

如果符号相反,你就错了。如果符号相同,则为真。

于 2008-09-15T21:25:30.563 回答

This answer is useful

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);

}

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

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

于 2008-09-15T22:45:33.757 回答

This answer is useful

3

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

假设非零等。

于 2008-09-15T20:58:17.320 回答

This answer is useful

2

作为技术说明,即使在现代架构上,位复杂的解决方案也将比乘法更有效。您只节省了大约 3 个周期,但您知道他们所说的“节省一分钱”...

于 2008-09-15T21:04:56.680 回答

This answer is useful

1

就在我的头顶...

int mask = 1 << 31;

(a & mask) ^ (b & mask) < 0;

于 2008-09-15T20:59:37.223 回答

This answer is useful

1

if (a*b < 0) 符号不同,否则符号相同(或 a 或 b 为零)

于 2008-09-15T21:00:12.420 回答

This answer is useful

1

对于具有二进制补码算术的任何大小的 int:

#define SIGNBIT (~((unsigned int)-1 >> 1))

if ((x & SIGNBIT) == (y & SIGNBIT))

// signs are the same

于 2008-09-15T21:15:32.740 回答

This answer is useful

1

假设 32 位

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

if(x*y>0)...由于溢出,答案很糟糕

于 2008-09-15T21:18:07.930 回答

This answer is useful

1

无分支 C 版本:

int sameSign(int a, int b) {

return ~(a^b) & (1<<(sizeof(int)*8-1));

}

整数类型的 C++ 模板:

template T sameSign(T a, T b) {

return ~(a^b) & (1<<(sizeof(T)*8-1));

}

于 2011-06-02T14:18:52.097 回答

This answer is useful

0

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

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

于 2008-09-15T21:01:27.203 回答

This answer is useful

0

int same_sign = !( (x >> 31) ^ (y >> 31) );

if (same_sign) ... 否则 ...

于 2008-09-15T21:04:14.593 回答

This answer is useful

0

使用std::signbit的更好方法如下:

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

它还支持其他基本类型(double,float等char)。

于 2015-12-01T22:16:58.890 回答

This answer is useful

0

#include

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

}

}

于 2021-05-22T13:20:21.853 回答