当我们实现二分查找时,类似实现以如下代码
public class BinarySearch {
public static int BinarySearchBasic(int[] a, int target) {
int i = 0, j = a.length - 1;
while (i <= j) {
int mid = (i + j) / 2;
if (target < a[mid]) {
j = mid - 1;
} else if (target > a[mid]) {
i = mid + 1;
} else {
return mid;
}
}
return -1;
}
}
我们来看如下代码:
@Test
public void signedTest() {
int i = 0;
int j = Integer.MAX_VALUE - 1;
int mid = (i + j) / 2;
System.out.println(mid);
i = mid + 1;
mid = (i + j) / 2;
System.out.println(mid);
}
代码中模仿了二分查找的部分步骤,该测试代码的运行结果如下:
这个结果很明显是有问题的,之所以是这种情况是因为符号位
举个栗子:
二进制数:`1111_1111`不把最高位当成符号位时,它是255。把最高位当成符号位时符号位时,它是-1。(最高位就是最左边的数)
在java中,会把二进制数的最高位看成符号位(1代表负号,0代表正号)
也就是说出现上面的输出情况是因为第一次打印时最高位位0,第二次打印时最高位为1
如何转化:
如果是有符号数,题中给的是补码,最左边的1表示负,仅考虑剩下的
111 1111 1111 1111 ,减去1后,得反码,即
1111 1111 1111 1110 ,按位取反,得原码,即
1000 0000 0000 0001 ,最左边的1仅表示负号,
所以转为十进制数,加上符号,得 - 1 。
这个过程就是将原码求补码的过程倒过来。
如果是无符号数,则
1111 1111 1111 1111 = 2^16 - 1 = 65535
如何避免java中对于最高位作为符号位的考虑?
先介绍