最快的两个数字符号比较,包括零
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;
}
考虑到符号可以是正数、负数或零,查找两个数字是否具有相同符号的最快方法是什么。
通常,你可以这样说两个数字具有相同的符号:
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;
}