I find that this function is one of the biggest causes of slow program execution. I can write a square root version with BigInteger only, but with the cube root, the algorithm sometimes gets caught in an endless loop unless I also use BigDecimal, because the values of r
and s
never reach equilibrium. I've already used tricks like leftShift
to multiply by 2 and s.multiply(s)
in place of s.pow(2)
to make it faster, but having to use BigDecimal is still slowing it down. Any idea how I could approach this problem?
public static BigDecimal THREE_D=BigDecimal.valueOf(3);
public static int UP=BigDecimal.ROUND_HALF_UP;
// other statements
public static BigInteger cbrt(BigInteger n)
{
BigDecimal m=new BigDecimal(n); // BigDecimal copy
BigInteger r=BigInteger.ZERO.setBit(n.bitLength()/3); // initial estimate
for(BigDecimal s=BigDecimal.ZERO; // different from r
!r.equals(s.toBigInteger()); // loop test: does r=s?
s=new BigDecimal(r),r=new BigDecimal(r.shiftLeft(1)) // Convert to BigDecimal,
.add(m.divide(s.multiply(s),UP)) // do the tricky division,
.divide(THREE_D,UP).toBigInteger()); // and convert back.
return r; // return the value
}
Edit: Followup to this question can be found here.
r <= s
. See ideone.com/QH2cFe. \$\endgroup\$