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

时间:2017-02-07 21:40:23

标签: java bit-manipulation sign zero

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

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

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

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

int1 ^ int2 >= 0;
然而,这是假设零为正。有哪些方法会返回true,包括零。

错误的一些例子是:

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

其中test将产生true而不是false。

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

我会发布一个尝试过的解决方案,但我找不到一个能胜过原来的解决方案。

编辑:我发现此处发现了类似的问题:Fastest way to check if two integers are on the same side of 0 我问是否有办法找到标志是否相同,包括零。所以1和1之间的比较是正确的,-1和-1是真,0和0是真,0和1是假,0和-1是假,等等。这与上面提到的问题不同!

3 个答案:

答案 0 :(得分:2)

这是我想出的:

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

答案 1 :(得分: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&lt; 0
  • 0,x == 0
  • 1,对于x> 0

它也为Integer.MIN_VALUE提供0,但是因为在你的情况下永远不会发生这种情况。

答案 2 :(得分:0)

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

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