最快的两个数字符号比较,包括零

Fastest Two Number Sign Comparison Including Zero

考虑到符号可以是正数、负数或零,查找两个数字是否具有相同符号的最快方法是什么。

通常,你可以这样说两个数字具有相同的符号:

Math.signum(int1) == Math.signum(int2);

您可以使用以下方法对其进行优化:

int1 ^ int2 >= 0;

但是,这是假设零为正。有哪些方法可以 return 为真,包括零。

一些错误示例如下:

a = 0; b = 1;
boolean test = a ^ b >= 0

其中测试将产生 true 而不是 false。

我 运行 一些测试平台,发现按位函数 returns 值快了将近 4 个数量级。由于这是我将在每个节点的非常大的树中使用的函数,因此我需要尽可能地优化它。

我会 post 一个尝试的解决方案,但我找不到比原始解决方案更好的解决方案。

编辑:我发现这里有一个类似的问题:Fastest way to check if two integers are on the same side of 0 我问是否有办法找到符号是否相同,包括零。所以比较 1 和 1 是真的,-1 和 -1 是真的,0 和 0 是真的,0 和 1 是假的,0 和 -1 是假的,等等。这和上面问的问题不是一回事!

您可以使用 signum 的整数版本,例如(未测试):

int signum(int x) {
    int m = x >> 31;
    int neg_m = -x >> 31;
    return m - neg_m;
}

此处 m 将是 -1 iff x < 0(否则为 0),并且 neg_m 将是 -1 iff x > 0(忽略 Integer.MIN_VALUE) .他们的区别是,

  • -1,对于 x < 0
  • 0,因为 x == 0
  • 1,对于 x > 0

它还为 Integer.MIN_VALUE 给出 0,但由于在您的情况下从未发生过这种情况,所以应该无关紧要。

如果没有对此进行基准测试,我怀疑你是否能比

做得更好
sameSign = a < 0 ? b < 0 : ( a == 0 ) == ( b == 0 );

这是我想出的:

private static boolean signcmp(int x, int y) {
    return ((( x >> 31) | (-x >>> 31)) ^ (( y >> 31) | (-y >>> 31))) == 0; 
}