2

So I need to sqrt a BigInteger in pre Java 9 and I found below function to do that. I do understand the code, but I don't really get why its there. So I guess I don't really get the math behind it. Like why is (n / 32 + 8) used. Why is mid calculated the way it is. etc.

    BigInteger a = BigInteger.ONE;
    BigInteger b = n.shiftRight(5).add(BigInteger.valueOf(8));
    while (b.compareTo(a) >= 0) {
        BigInteger mid = a.add(b).shiftRight(1);
        if (mid.multiply(mid).compareTo(n) > 0) {
            b = mid.subtract(BigInteger.ONE);
        } else {
            a = mid.add(BigInteger.ONE);
        }
    }
    return a.subtract(BigInteger.ONE);
}

2 Answers2

5

EDIT: James Reinstate Monica Polk is correct, this is not the Babylonian Method but rather the Bisection method. I did not look at the code carefully enough before answering. Please see his answer as it is more accurate than mine.

This looks to be the Babylonian Method for approximating square roots. (n/32 + 8) is just used as a "seed", as providing a sane starting value can provide a better approximation in fewer iterations than just picking any number.

2

The algorithm is the bisection method applied to finding the zero of the polynomial x2 - n = 0. Why is (n / 32 + 8) used as a seed? I have no idea as it is a rather poor approximation. A much better approximation that is almost as cheap to compute is n.shiftRight(n.bitLength()/2);

President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
  • You are correct, I didn't look closely enough at the code before answering, and I wasn't aware of the bisection method before my answer. Thank you for the correction. – VimGoodEmacsBad Nov 08 '19 at 20:07