Java 检查两个整数是否在0的同一侧的最快方法
我需要多次检查两个整数是否在零的同一侧。我不在乎它是积极的还是消极的,只是它是同一面。。。而性能是非常重要的 目前我正在这样做:Java 检查两个整数是否在0的同一侧的最快方法,java,performance,xor,Java,Performance,Xor,我需要多次检查两个整数是否在零的同一侧。我不在乎它是积极的还是消极的,只是它是同一面。。。而性能是非常重要的 目前我正在这样做: if (int1 == 0 || int2 == 0) { // handle zero } else if ((int1 ^ int2) > 0) { // different side } else { // same side } 这是一个30%的速度提高(测试)比更明显的: if ((int1 > 0 &&
if (int1 == 0 || int2 == 0) {
// handle zero
} else if ((int1 ^ int2) > 0) {
// different side
} else {
// same side
}
这是一个30%的速度提高(测试)比更明显的:
if ((int1 > 0 && int2 > 0) || (int1 < 0 && int2 < 0)) {
看起来@aaronman是赢家我会将它们位转换为无符号整数,并对MSB(最高有效位)进行异或-比任何比较(进行减法)或乘法都快得多
int int1 = 3;
int int2 = 4;
boolean res = ( (int1 * int2) >= 0) ? true : false;
System.out.println(res);
比较符号位
return ((n >> 31) ^ (n2 >> 31) ) == 0 ? /* same */ : /* different */;
比较符号位的另一种方法
return (((int1 & 0x80000000) ^ (int2 & 0x80000000))) == 0 ? /* same */ : /* different */;
我刚刚验证了Op的代码在int1==int2
时是错误的。如果以下内容相同,则它们将始终打印不同的内容
if (int1 == 0 || int2 == 0) {
// handle zero
} else if ((int1 ^ int2) < 0) {
// same side
} else {
// different side
}
if(int1==0 | | int2==0){
//处理零
}如果((int1^int2)<0,则为else{
//同一边
}否则{
//不同方面
}
或
两者的想法是相同的——去掉符号位以外的所有字符,然后比较是否相等。我不确定哪个更快,右移(>>)还是按位and(&)。另一个答案
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
}
(int1^int2)>>31==0/*同侧*/:/*不同侧*/代码>这不一定能正确处理0我不确定在这种情况下您想做什么。
编辑:还想指出,如果这是在c而不是java中,那么可以通过去掉==0
来进一步优化,因为Boolean在c中的工作方式,只是出于好奇,情况会发生变化,你是如何检查速度的?另外,我建议不要把零放在第一位,因为这可能是最不可能的。另外,对于同一个符号,它不应该是(int1^int2)<0
?(int1^int2)<0
使用2个可以由硬件直接处理的操作。没有比这更快的了。我接受你的精彩问题,它应该被标记为“答案陷阱”。每个人在这个问题上都尝试过,但似乎都被否决了。也许你的是唯一的解决方案?这对int1==int2有效吗?虽然这不能解决问题,但你需要知道它是哪一个-零或同侧性能,这并不总是有效的。请参见try:int1=1200000000;int2=150000000代码>但这只是OP的解决方案。我认为另一个答案应该是快速而正确的。我现在看到Ops代码不是,它应该是0
->不同的方面首先是正确的,但这会让它慢下来一点,我的答案与你的基准相比如何?我的,我相信更快,因为我只使用右移一次,而你使用了两次,我改变了你的概念仍然存在,我不是java专家,但我相当肯定您可以做类似的事情:(int1&0x80000000000000l)^(int2&0x80000000000000l),给出或接受语法问题,当然是基于您的整数大小。这里也提到了-Javaok中没有未签名的int,所以除了强制转换之外,这与上面建议的有什么不同?切换括号并说(int1^int2)&0x80000000000000与(int1^int2)>>31完全相同。我叫dibs:)@durron597-我已经把按位和的版本放回了。第二个答案和@greedybuddha的答案一样,呃,不是,但我已经把他改成了那个哈哈。即将进行大编辑。无法将int
转换为bool
,对不起,我很确定这是最快的答案。我计划稍后再勾选,除非有人想出更好的方法。然后有人应该给我一个厨师,我喜欢你的位子移动的方式;)为什么要换班?(int1^int2)>=0?相同:不同应产生完全相同的结果result@Durandal我想在c中我的答案是你可以去掉==但是如果你想自己检查速度,我没有做测试,只是回答了问题
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
}
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
}