BigDecimalMath { public static BigDecimal root(BigDecimal x, BigDecimal n, MathContext mathContext) { checkMathContext(mathContext); switch (n.signum()) { case -1: case 0: throw new ArithmeticException("Illegal root(x, n) for n <= 0: n = " + n); } switch (x.signum()) { case 0: return ZERO; case -1: throw new ArithmeticException("Illegal root(x, n) for x < 0: x = " + x); } if (isDoubleValue(x) && isDoubleValue(n)) { double initialResult = Math.pow(x.doubleValue(), 1.0 / n.doubleValue()); if (Double.isFinite(initialResult)) { return rootUsingNewtonRaphson(x, n, BigDecimal.valueOf(initialResult), mathContext); } } MathContext mc = new MathContext(mathContext.getPrecision() + 6, mathContext.getRoundingMode()); return pow(x, BigDecimal.ONE.divide(n, mc), mathContext); } private  BigDecimalMath(); static BigDecimal toBigDecimal(String string); static BigDecimal toBigDecimal(String string, MathContext mathContext); static boolean isIntValue(BigDecimal value); static boolean isLongValue(BigDecimal value); static boolean isDoubleValue(BigDecimal value); static BigDecimal mantissa(BigDecimal value); static int exponent(BigDecimal value); static int significantDigits(BigDecimal value); static BigDecimal integralPart(BigDecimal value); static BigDecimal fractionalPart(BigDecimal value); static BigDecimal round(BigDecimal value, MathContext mathContext); static BigDecimal roundWithTrailingZeroes(BigDecimal value, MathContext mathContext); static BigDecimal reciprocal(BigDecimal x, MathContext mathContext); static BigDecimal factorial(int n); static BigDecimal factorial(BigDecimal x, MathContext mathContext); static BigDecimal gamma(BigDecimal x, MathContext mathContext); static BigDecimal bernoulli(int n, MathContext mathContext); static BigDecimal pow(BigDecimal x, BigDecimal y, MathContext mathContext); static BigDecimal pow(BigDecimal x, long y, MathContext mathContext); static BigDecimal sqrt(BigDecimal x, MathContext mathContext); static BigDecimal root(BigDecimal x, BigDecimal n, MathContext mathContext); static BigDecimal log(BigDecimal x, MathContext mathContext); static BigDecimal log2(BigDecimal x, MathContext mathContext); static BigDecimal log10(BigDecimal x, MathContext mathContext); static BigDecimal pi(MathContext mathContext); static BigDecimal e(MathContext mathContext); static BigDecimal exp(BigDecimal x, MathContext mathContext); static BigDecimal sin(BigDecimal x, MathContext mathContext); static BigDecimal asin(BigDecimal x, MathContext mathContext); static BigDecimal cos(BigDecimal x, MathContext mathContext); static BigDecimal acos(BigDecimal x, MathContext mathContext); static BigDecimal tan(BigDecimal x, MathContext mathContext); static BigDecimal atan(BigDecimal x, MathContext mathContext); static BigDecimal atan2(BigDecimal y, BigDecimal x, MathContext mathContext); static BigDecimal cot(BigDecimal x, MathContext mathContext); static BigDecimal acot(BigDecimal x, MathContext mathContext); static BigDecimal sinh(BigDecimal x, MathContext mathContext); static BigDecimal cosh(BigDecimal x, MathContext mathContext); static BigDecimal tanh(BigDecimal x, MathContext mathContext); static BigDecimal coth(BigDecimal x, MathContext mathContext); static BigDecimal asinh(BigDecimal x, MathContext mathContext); static BigDecimal acosh(BigDecimal x, MathContext mathContext); static BigDecimal atanh(BigDecimal x, MathContext mathContext); static BigDecimal acoth(BigDecimal x, MathContext mathContext);  }
@Test public void testRoot() { for(double n : new double[] { 0.1, 0.9, 1, 1.1, 2, 10, 33.3333, 1234.5678 }) { for (double x : new double[]{ 0, 0.1, 0.9, 1, 1.1, 2, 10, 33.3333, 1234.5678 }) { System.out.println("ROOT x=" + x + " n=" + n); assertBigDecimal( "root(2," + x + ")", toCheck(Math.pow(x, 1.0 / n)), BigDecimalMath.root(BigDecimal.valueOf(x), BigDecimal.valueOf(n), MC), MC_CHECK_DOUBLE); } } }
@Test(expected = ArithmeticException.class) public void testRootZeroN() { BigDecimalMath.root(BigDecimal.ONE, BigDecimal.ZERO, MC); }
@Test(expected = ArithmeticException.class) public void testRootNegativeN() { BigDecimalMath.root(BigDecimal.ONE, new BigDecimal(-1), MC); }
@Test(expected = ArithmeticException.class) public void testRootNegativeX() { BigDecimalMath.root(new BigDecimal(-1), BigDecimal.ONE, MC); }
@Test(expected = UnsupportedOperationException.class) public void testRootUnlimitedFail() { BigDecimalMath.root(BigDecimal.valueOf(1.2), BigDecimal.valueOf(2), MathContext.UNLIMITED); }
@Test public void testRootRandom() { assertRandomCalculation( adaptCount(100), "root", random -> random.nextDouble() * 10 + 0.000001, random -> random.nextDouble() * 5, null, (x, y, mathContext) -> BigDecimalMath.root(x, y, mathContext)); }
@Test(expected = ArithmeticException.class) public void testRootNegative() { BigDecimalMath.root(new BigDecimal(-1), BigDecimal.ONE, MC); }