BigDecimalMath { public static BigDecimal log(BigDecimal x, MathContext mathContext) { checkMathContext(mathContext); if (x.signum() <= 0) { throw new ArithmeticException("Illegal log(x) for x <= 0: x = " + x); } if (x.compareTo(ONE) == 0) { return ZERO; } BigDecimal result; switch (x.compareTo(TEN)) { case 0: result = logTen(mathContext); break; case 1: result = logUsingExponent(x, mathContext); break; default : result = logUsingTwoThree(x, mathContext); } return round(result, 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 testLogRange100() { double step = getRangeStep(1.0); BigDecimalStream.range(step, 100.0, step, MC).forEach(x -> { System.out.println("Testing log(" + x + ")"); assertBigDecimal("log(" + x + ")", toCheck(Math.log(x.doubleValue())), BigDecimalMath.log(x, MC), MC_CHECK_DOUBLE); BigDecimal finalX = x; assertPrecisionCalculation( mathContext -> BigDecimalMath.log(finalX, mathContext), 10, AUTO_TEST_MAX_PRECISION); }); }
@Test public void testLogNotorious1() { BigDecimal expected = new BigDecimal("1.28840586030076531271916787589963460174688352499997906354516854751071684132712190465267938913524540189227183498685955203091012976295191938570887410037177795976156712449887694786077349630415919676796628382920641191635039097198525638716788242413712812154035694161623839896238526801424419472197899141291552341986057193552767761847325665588799624460996389716450246797586099819246857022106263044473561032621692801928684892761931286774706996443604259279886700716"); assertPrecisionCalculation( expected, mathContext -> BigDecimalMath.log(new BigDecimal("3.627"), mathContext), 10); }
@Test public void testLogRandom() { assertRandomCalculation( adaptCount(100), "log", random -> random.nextDouble() * 100 + 0.00001, Math::log, (x, mathContext) -> BigDecimalMath.log(x, mathContext)); }
@Test(expected = ArithmeticException.class) public void testLogNegative() { BigDecimalMath.log(BigDecimal.valueOf(-1), MC); }
@Test(expected = UnsupportedOperationException.class) public void testLogUnlimitedFail() { BigDecimalMath.log(BigDecimal.valueOf(2), MathContext.UNLIMITED); }
@Test public void testLogRange10() { double step = getRangeStep(0.1); BigDecimalStream.range(step, 10.0, step, MC).forEach(x -> { System.out.println("Testing log(" + x + ")"); assertBigDecimal("log(" + x + ")", toCheck(Math.log(x.doubleValue())), BigDecimalMath.log(x, MC), MC_CHECK_DOUBLE); BigDecimal finalX = x; assertPrecisionCalculation( mathContext -> BigDecimalMath.log(finalX, mathContext), 10, AUTO_TEST_MAX_PRECISION); }); }