Arrays中的二分查找

24 篇文章 0 订阅

#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的实现思路

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多年码龄的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值