Calculating nth root in Java using power method

后端 未结 9 2655
礼貌的吻别
礼貌的吻别 2021-02-18 22:08

I was trying to get a cubic root in java using Math.pow(n, 1.0/3) but because it divides doubles, it doesn\'t return the exact answer. For example, with 125, this g

9条回答
  •  孤独总比滥情好
    2021-02-18 22:42

    I wrote this method to compute floor(x^(1/n)) where x is a non-negative BigInteger and n is a positive integer. It was a while ago now so I can't explain why it works, but I'm reasonably confident that when I wrote it I was happy that it's guaranteed to give the correct answer reasonably quickly.

    To see if x is an exact n-th power you can check if the result raised to the power n gives you exactly x back again.

    public static BigInteger floorOfNthRoot(BigInteger x, int n) {
        int sign = x.signum();
        if (n <= 0 || (sign < 0))
            throw new IllegalArgumentException();
        if (sign == 0)
            return BigInteger.ZERO;
        if (n == 1)
            return x;
        BigInteger a;
        BigInteger bigN = BigInteger.valueOf(n);
        BigInteger bigNMinusOne = BigInteger.valueOf(n - 1);
        BigInteger b = BigInteger.ZERO.setBit(1 + x.bitLength() / n);
        do {
            a = b;
            b = a.multiply(bigNMinusOne).add(x.divide(a.pow(n - 1))).divide(bigN);
        } while (b.compareTo(a) == -1);
        return a;
    }
    

    To use it:

    System.out.println(floorOfNthRoot(new BigInteger("125"), 3));
    

    Edit Having read the comments above I now remember that this is the Newton-Raphson method for n-th roots. The Newton-Raphson method has quadratic convergence (which in everyday language means it's fast). You can try it on numbers which have dozens of digits and you should get the answer in a fraction of a second.

    You can adapt the method to work with other number types, but double and BigDecimal are in my view not suited for this kind of thing.

提交回复
热议问题