#JDK对你最有触动的代码#
Arrays中的二分查找方法(以double为例)
// 片段1
private static int binarySearch0(double[] a, int fromIndex, int toIndex,
double key) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
double midVal = a[mid];
if (midVal < key)
low = mid + 1; // Neither val is NaN, thisVal is smaller
else if (midVal > key)
high = mid - 1; // Neither val is NaN, thisVal is larger
else {
long midBits = Double.doubleToLongBits(midVal);
long keyBits = Double.doubleToLongBits(key);
if (midBits == keyBits) // Values are equal
return mid; // Key found
else if (midBits < keyBits) // (-0.0, 0.0) or (!NaN, NaN)
low = mid + 1;
else // (0.0, -0.0) or (NaN, !NaN)
high = mid - 1;
}
}
return -(low + 1); // key not found.
}
// 片段2 Double类中的代码
public static long doubleToLongBits(double value) {
long result = doubleToRawLongBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
DoubleConsts.EXP_BIT_MASK) &&
(result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
result = 0x7ff8000000000000L;
return result;
}
1. 面试中基本上都绕不开二分查找,有时候会到网上找一些例子,其实JDK中的例子非常标准和规范。
2. 对于中间值的选取,采用了无符号位操作,int mid = (low + high) >>> 1;
常规的写法 (low + high) / 2会存在运算溢出的可能。low + (high - low) / 2 运算不够高效。
而JDK的写法可以完美解决。
3. 上述代码中选取的是double的比较,由于浮点数的精度问题,对于double的比较,也是我们经常遇到的问题
对于片段2中的代码注释中,详细解释了IEEE 754 floating-point双精度浮点数的存储格式。
Bit 63(符号位): represents the sign of the floating-point number
Bits 62-52(指数位): represent the exponent.
Bits 51-0(有效数字位): represent the significand (sometimes called the mantissa) of the floating-point number
#感触#
1. 掌握必要的计算机知识对看懂源码非常重要
2. 当遇到一些问题的时候,可以尝试看一下JDK的实现思路