我需要检查两个整数是否在零的同一侧多次。我不在乎它是积极的还是消极的,只是它是同一面......并且表现非常重要。
目前我正在这样做:
if (int1 == 0 || int2 == 0) {
// handle zero
} else if ((int1 ^ int2) > 0) {
// different side
} else {
// same side
}
速度提高30%(使用caliper进行测试)更明显:
if ((int1 > 0 && int2 > 0) || (int1 < 0 && int2 < 0)) {
可以更快地完成吗?
If anyone wants to see the test framework I'm using for the 30%, it's here. I used caliper 0.5-rc1
注意:所有这些解决方案都会检查第一位,基本上,零与正数相同。因此,如果这适用于您的应用程序,则无需进行零检查。
基准列表:
((&&)||(&&))
解决方案(>>31) == (>>31)
(0x80000000)
==
而不是^
(^)>>31 == 0
0% Scenario{vm=java, trial=0, benchmark=XOR} 1372.83 ns; ?=7.16 ns @ 3 trials
17% Scenario{vm=java, trial=0, benchmark=Ifs} 2397.32 ns; ?=16.81 ns @ 3 trials
33% Scenario{vm=java, trial=0, benchmark=Bits} 1311.75 ns; ?=3.04 ns @ 3 trials
50% Scenario{vm=java, trial=0, benchmark=XorShift} 1231.24 ns; ?=12.11 ns @ 5 trials
67% Scenario{vm=java, trial=0, benchmark=BitAndXor} 1446.60 ns; ?=2.28 ns @ 3 trials
83% Scenario{vm=java, trial=0, benchmark=BitAndEquals} 1492.37 ns; ?=14.62 ns @ 3 trials
benchmark us linear runtime
XOR 1.37 =================
Ifs 2.40 ==============================
Bits 1.31 ================
XorShift 1.23 ===============
BitAndXor 1.45 ==================
BitAndEquals 1.49 ==================
vm: java
trial: 0
看起来@aaronman是赢家
答案 0 :(得分:12)
(int1 ^ int2) >> 31 == 0 ? /*on same side*/ : /*different side*/ ;
这不一定正确处理0我不确定在这种情况下你想做什么。
编辑:还想指出,如果这是在c而不是java,它可以通过摆脱== 0
进一步优化,因为布尔在c中的工作方式,案例将被切换
答案 1 :(得分:2)
if (int1 == 0 || int2 == 0) {
// handle zero
} else if ((int1 >> 31) == (int2 >> 31)) {
// same side
} else {
// different side
}
或
if (int1 == 0 || int2 == 0) {
// handle zero
} else if ((int1 & Integer.MIN_VALUE) == (int2 & Integer.MIN_VALUE)) {
// same side
} else {
// different side
}
两者的想法是相同的 - 除了符号位之外的所有内容,然后将其进行比较以获得相等性。我不确定哪个更快,右移(&gt;&gt;)或按位和(&amp;)。
答案 2 :(得分:1)
我会把它们变成unsigned int,而xor是MSB(最重要的位) - 比任何比较(减法)或乘法快得多
答案 3 :(得分:1)
替代答案
比较符号位
return ((n >> 31) ^ (n2 >> 31) ) == 0 ? /* same */ : /* different */;
比较符号位的替代方法
return (((int1 & 0x80000000) ^ (int2 & 0x80000000))) == 0 ? /* same */ : /* different */;
我刚刚验证过,int1 == int2
时Op的代码错误。如果它们相同,则以下内容将始终不同。
if (int1 == 0 || int2 == 0) {
// handle zero
} else if ((int1 ^ int2) < 0) {
// same side
} else {
// different side
}
答案 4 :(得分:0)
另一个答案......
final int i = int1 ^ int2;
if (i == 0 && int1 == 0) {
// both are zero
} else if (i & Integer.MIN_VALUE == Integer.MIN_VALUE) {
// signs differ
} else {
// same sign
}
答案 5 :(得分:-4)
int int1 = 3;
int int2 = 4;
boolean res = ( (int1 * int2) >= 0) ? true : false;
System.out.println(res);