List of usage examples for java.math BigDecimal pow
public BigDecimal pow(int n, MathContext mc)
(thisn)
. From source file:Main.java
public static void main(String[] args) { MathContext mc = new MathContext(4); // 4 precision BigDecimal bg1 = new BigDecimal("2.17"); BigDecimal bg2 = bg1.pow(3, mc); System.out.println(bg2);/*from w w w . ja va 2 s . co m*/ }
From source file:Main.java
public static BigDecimal cuberoot(BigDecimal b) { // Specify a math context with 40 digits of precision. MathContext mc = new MathContext(40); BigDecimal x = new BigDecimal("1", mc); // Search for the cube root via the Newton-Raphson loop. Output each // successive iteration's value. for (int i = 0; i < ITER; i++) { x = x.subtract(//from w ww .ja v a2s .c o m x.pow(3, mc).subtract(b, mc).divide(new BigDecimal("3", mc).multiply(x.pow(2, mc), mc), mc), mc); } return x; }
From source file:Main.java
public static BigDecimal cuberoot(BigDecimal b) { // Specify a math context with 40 digits of precision. MathContext mc = new MathContext(40); BigDecimal x = new BigDecimal("1", mc); // Search for the cube root via the Newton-Raphson loop. Output each // // successive iteration's value. for (int i = 0; i < ITER; i++) { x = x.subtract(//from w w w . ja va2s. c om x.pow(3, mc).subtract(b, mc).divide(new BigDecimal("3", mc).multiply(x.pow(2, mc), mc), mc), mc); } return x; }
From source file:org.nd4j.linalg.util.BigDecimalMath.java
/** * The exponential function.//from www . j a v a2 s . co m * * @param x the argument. * @return exp(x). * The precision of the result is implicitly defined by the precision in the argument. * 16 * In particular this means that "Invalid Operation" errors are thrown if catastrophic * cancellation of digits causes the result to have no valid digits left. */ static public BigDecimal exp(BigDecimal x) { /* To calculate the value if x is negative, use exp(-x) = 1/exp(x) */ if (x.compareTo(BigDecimal.ZERO) < 0) { final BigDecimal invx = exp(x.negate()); /* Relative error in inverse of invx is the same as the relative errror in invx. * This is used to define the precision of the result. */ MathContext mc = new MathContext(invx.precision()); return BigDecimal.ONE.divide(invx, mc); } else if (x.compareTo(BigDecimal.ZERO) == 0) { /* recover the valid number of digits from x.ulp(), if x hits the * zero. The x.precision() is 1 then, and does not provide this information. */ return scalePrec(BigDecimal.ONE, -(int) (Math.log10(x.ulp().doubleValue()))); } else { /* Push the number in the Taylor expansion down to a small * value where TAYLOR_NTERM terms will do. If x<1, the n-th term is of the order * x^n/n!, and equal to both the absolute and relative error of the result * since the result is close to 1. The x.ulp() sets the relative and absolute error * of the result, as estimated from the first Taylor term. * We want x^TAYLOR_NTERM/TAYLOR_NTERM! < x.ulp, which is guaranteed if * x^TAYLOR_NTERM < TAYLOR_NTERM*(TAYLOR_NTERM-1)*...*x.ulp. */ final double xDbl = x.doubleValue(); final double xUlpDbl = x.ulp().doubleValue(); if (Math.pow(xDbl, TAYLOR_NTERM) < TAYLOR_NTERM * (TAYLOR_NTERM - 1.0) * (TAYLOR_NTERM - 2.0) * xUlpDbl) { /* Add TAYLOR_NTERM terms of the Taylor expansion (Eulers sum formula) */ BigDecimal resul = BigDecimal.ONE; /* x^i */ BigDecimal xpowi = BigDecimal.ONE; /* i factorial */ BigInteger ifac = BigInteger.ONE; /* TAYLOR_NTERM terms to be added means we move x.ulp() to the right * for each power of 10 in TAYLOR_NTERM, so the addition wont add noise beyond * whats already in x. */ MathContext mcTay = new MathContext(err2prec(1., xUlpDbl / TAYLOR_NTERM)); for (int i = 1; i <= TAYLOR_NTERM; i++) { ifac = ifac.multiply(new BigInteger("" + i)); xpowi = xpowi.multiply(x); final BigDecimal c = xpowi.divide(new BigDecimal(ifac), mcTay); resul = resul.add(c); if (Math.abs(xpowi.doubleValue()) < i && Math.abs(c.doubleValue()) < 0.5 * xUlpDbl) { break; } } /* exp(x+deltax) = exp(x)(1+deltax) if deltax is <<1. So the relative error * in the result equals the absolute error in the argument. */ MathContext mc = new MathContext(err2prec(xUlpDbl / 2.)); return resul.round(mc); } else { /* Compute exp(x) = (exp(0.1*x))^10. Division by 10 does not lead * to loss of accuracy. */ int exSc = (int) (1.0 - Math.log10(TAYLOR_NTERM * (TAYLOR_NTERM - 1.0) * (TAYLOR_NTERM - 2.0) * xUlpDbl / Math.pow(xDbl, TAYLOR_NTERM)) / (TAYLOR_NTERM - 1.0)); BigDecimal xby10 = x.scaleByPowerOfTen(-exSc); BigDecimal expxby10 = exp(xby10); /* Final powering by 10 means that the relative error of the result * is 10 times the relative error of the base (First order binomial expansion). * This looses one digit. */ MathContext mc = new MathContext(expxby10.precision() - exSc); /* Rescaling the powers of 10 is done in chunks of a maximum of 8 to avoid an invalid operation 17 * response by the BigDecimal.pow library or integer overflow. */ while (exSc > 0) { int exsub = Math.min(8, exSc); exSc -= exsub; MathContext mctmp = new MathContext(expxby10.precision() - exsub + 2); int pex = 1; while (exsub-- > 0) { pex *= 10; } expxby10 = expxby10.pow(pex, mctmp); } return expxby10.round(mc); } } }
From source file:org.nd4j.linalg.util.BigDecimalMath.java
/** * Raise to an integer power and round./*from ww w . j av a 2s . c o m*/ * * @param x The base. * @param n The exponent. * @return x^n. */ static public BigDecimal powRound(final BigDecimal x, final int n) { /* The relative error in the result is n times the relative error in the input. * The estimation is slightly optimistic due to the integer rounding of the logarithm. */ MathContext mc = new MathContext(x.precision() - (int) Math.log10((double) (Math.abs(n)))); return x.pow(n, mc); }
From source file:org.nd4j.linalg.util.BigDecimalMath.java
/** * The Gamma function.//from ww w . j a v a 2s.c o m * * @param x The argument. * @return Gamma(x). */ static public BigDecimal Gamma(final BigDecimal x) { /* reduce to interval near 1.0 with the functional relation, Abramowitz-Stegun 6.1.33 */ if (x.compareTo(BigDecimal.ZERO) < 0) { return divideRound(Gamma(x.add(BigDecimal.ONE)), x); } else if (x.doubleValue() > 1.5) { /* Gamma(x) = Gamma(xmin+n) = Gamma(xmin)*Pochhammer(xmin,n). */ int n = (int) (x.doubleValue() - 0.5); BigDecimal xmin1 = x.subtract(new BigDecimal(n)); return multiplyRound(Gamma(xmin1), pochhammer(xmin1, n)); } else { /* apply Abramowitz-Stegun 6.1.33 */ BigDecimal z = x.subtract(BigDecimal.ONE); /* add intermediately 2 digits to the partial sum accumulation */ z = scalePrec(z, 2); MathContext mcloc = new MathContext(z.precision()); /* measure of the absolute error is the relative error in the first, logarithmic term */ double eps = x.ulp().doubleValue() / x.doubleValue(); BigDecimal resul = log(scalePrec(x, 2)).negate(); if (x.compareTo(BigDecimal.ONE) != 0) { BigDecimal gammCompl = BigDecimal.ONE.subtract(gamma(mcloc)); resul = resul.add(multiplyRound(z, gammCompl)); for (int n = 2;; n++) { /* multiplying z^n/n by zeta(n-1) means that the two relative errors add. * so the requirement in the relative error of zeta(n)-1 is that this is somewhat * smaller than the relative error in z^n/n (the absolute error of thelatter is the * absolute error in z) */ BigDecimal c = divideRound(z.pow(n, mcloc), n); MathContext m = new MathContext(err2prec(n * z.ulp().doubleValue() / 2. / z.doubleValue())); c = c.round(m); /* At larger n, zeta(n)-1 is roughly 1/2^n. The product is c/2^n. * The relative error in c is c.ulp/2/c . The error in the product should be small versus eps/10. * Error from 1/2^n is c*err(sigma-1). * We need a relative error of zeta-1 of the order of c.ulp/50/c. This is an absolute * error in zeta-1 of c.ulp/50/c/2^n, and also the absolute error in zeta, because zeta is * of the order of 1. */ if (eps / 100. / c.doubleValue() < 0.01) { m = new MathContext(err2prec(eps / 100. / c.doubleValue())); } else { m = new MathContext(2); } /* zeta(n) -1 */ BigDecimal zetm1 = zeta(n, m).subtract(BigDecimal.ONE); c = multiplyRound(c, zetm1); if (n % 2 == 0) { resul = resul.add(c); } else { resul = resul.subtract(c); } /* alternating sum, so truncating as eps is reached suffices */ if (Math.abs(c.doubleValue()) < eps) { break; } } } /* The relative error in the result is the absolute error in the * input variable times the digamma (psi) value at that point. */ double psi = 0.5772156649; double zdbl = z.doubleValue(); for (int n = 1; n < 5; n++) { psi += zdbl / n / (n + zdbl); } eps = psi * x.ulp().doubleValue() / 2.; mcloc = new MathContext(err2prec(eps)); return exp(resul).round(mcloc); } }