Package java.math

Examples of java.math.MathContext


        /* Specify an internal accuracy within the loop which is
         * slightly larger than what is demanded by 'eps' below.
         */
        final BigDecimal xhighpr = scalePrec(x, 2);
        MathContext mc = new MathContext(2 + x.precision());

        /*
         * Relative accuracy of the result is eps.
         */
        final double eps = x.ulp().doubleValue() / (2 * n * x.doubleValue());
        for (; ; ) {
            /* s = s -(s/n-x/n/s^(n-1)) = s-(s-x/s^(n-1))/n; test correction s/n-x/s for being
             * smaller than the precision requested. The relative correction is (1-x/s^n)/n,
             */
            BigDecimal c = xhighpr.divide(s.pow(n - 1), mc);
            c = s.subtract(c);
            MathContext locmc = new MathContext(c.precision());
            c = c.divide(nth, locmc);
            s = s.subtract(c);
            if (Math.abs(c.doubleValue() / s.doubleValue()) < eps)
                break;
        }
        return s.round(new MathContext(err2prec(eps)));
    } /* BigDecimalMath.root */
 
View Full Code Here


        /* truncate to the precision set by x and y. Absolute error = 2*x*xerr+2*y*yerr,
         * where the two errors are 1/2 of the ulp's.  Two intermediate protectio digits.
         */
        BigDecimal zerr = x.abs().multiply(x.ulp()).add(y.abs().multiply(y.ulp()));
        MathContext mc = new MathContext(2 + err2prec(z, zerr));

        /* Pull square root */
        z = sqrt(z.round(mc));

        /*
         * Final rounding. Absolute error in the square root is (y*yerr+x*xerr)/z, where zerr holds 2*(x*xerr+y*yerr).
         */
        mc = new MathContext(err2prec(z.doubleValue(), 0.5 * zerr.doubleValue() / z.doubleValue()));
        return z.round(mc);
    } /* BigDecimalMath.hypot */
 
View Full Code Here

        /* Truncate to the precision set by x. Absolute error = in z (square of the result) is |2*x*xerr|,
         * where the error is 1/2 of the ulp. Two intermediate protection digits.
         * zerr is a signed value, but used only in conjunction with err2prec(), so this feature does not harm.
         */
        double zerr = x.doubleValue() * x.ulp().doubleValue();
        MathContext mc = new MathContext(2 + err2prec(z.doubleValue(), zerr));

        /* Pull square root */
        z = sqrt(z.round(mc));

        /* Final rounding. Absolute error in the square root is x*xerr/z, where zerr holds 2*x*xerr.
         */
        mc = new MathContext(err2prec(z.doubleValue(), 0.5 * zerr / z.doubleValue()));
        return z.round(mc);
    } /* BigDecimalMath.hypot */
 
View Full Code Here

             */

            BigDecimal e = BigDecimal.ONE;
            BigDecimal t = BigDecimal.ONE;
            BigDecimal olde = e;
            MathContext nmc = _mc_adjust_exp_(x,mc); // more precision (exponent case)...
            int i = 1;
            do {
                olde = _dec_round_(e,mc);
                t = t.multiply(x.divide(new BigDecimal(i++),nmc),nmc);
                e = e.add(t);
View Full Code Here

            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 (Euler's 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 won't add noise beyond
                 * what's 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
                 * 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);
                }
View Full Code Here

                else
                    resul = resul.add(c);
                if (Math.abs(c.doubleValue()) < eps)
                    break;
            }
            MathContext mc = new MathContext(err2prec(resul.doubleValue(), eps));
            return resul.round(mc);
        }
        else {
            final double xDbl = x.doubleValue();
            final double xUlpDbl = x.ulp().doubleValue();

            /* Map log(x) = log root[r](x)^r = r*log( root[r](x)) with the aim
             * to move roor[r](x) near to 1.2 (that is, below the 0.3 appearing above), where log(1.2) is roughly 0.2.
             */
            int r = (int) (Math.log(xDbl) / 0.2);

            /* Since the actual requirement is a function of the value 0.3 appearing above,
             * we avoid the hypothetical case of endless recurrence by ensuring that r >= 2.
             */
            r = Math.max(2, r);

            /*
             * Compute r-th root with 2 additional digits of precision
             */
            BigDecimal xhighpr = scalePrec(x, 2);
            BigDecimal resul = root(r, xhighpr);
            resul = log(resul).multiply(new BigDecimal(r));

            /* error propagation: log(x+errx) = log(x)+errx/x, so the absolute error
             * in the result equals the relative error in the input, xUlpDbl/xDbl .
             */
            MathContext mc = new MathContext(err2prec(resul.doubleValue(), xUlpDbl / xDbl));
            return resul.round(mc);
        }
    } /* BigDecimalMath.log */
 
View Full Code Here

            /*
             * The standard Taylor series around x=1, z=0, z=x-1. Abramowitz-Stegun 4.124.
             * The absolute error is err(z)/(1+z) = err(x)/x.
             */
            BigDecimal z = x.subtract(BigDecimal.ONE);
            MathContext nmc = _mc_adjust_(z,_mc_plus2_(mc)); // more precision (the integer part include by _mc_adjust_)...
            BigDecimal zpown = z;
            BigDecimal resul = z;
            BigDecimal oldr = resul;
           
            int k = 2;
            do {
                oldr = _dec_round_(resul,mc);
                for(int j=2;j>0;j--){
                    zpown = zpown.multiply(z);
                    BigDecimal c = zpown.divide(new BigDecimal(k), nmc);

                    if (k++ % 2 == 0)
                        resul = resul.subtract(c);
                    else
                        resul = resul.add(c);

                    //System.out.println(k+" sqrt :"+resul.toPlainString());
                    //k++;
                }
            }
            while (_dec_round_(resul,mc).compareTo(oldr) != 0); // auto-adaptative algo for maximum precision

            return _dec_round_(resul,mc);
        }
        else {
            /*
             * Recursively log(x) = 2 * log(sqrt(x)) = log(sqrt(x)) + log(sqrt(x))
             */
            //System.out.print("-");
            MathContext nmc = _mc_adjust_(x,_mc_plus2_(mc)); // more precision (the integer part include by _mc_adjust_)...
            BigDecimal r2x = sqrt(x, nmc);
            //System.out.println("sqrt:"+r2x.toPlainString());
            BigDecimal log_r2x = log(r2x, nmc);
            //System.out.print("=");
            return _dec_round_(log_r2x.add(log_r2x),mc);
View Full Code Here

     */
    public static BigDecimal log10(BigDecimal x, MathContext mc) {
        /*
         * simply use log10=ln(x) / ln(10)..
         */
        MathContext nmc = _mc_adjust_(x,_mc_plus2_(mc)); // more precision (the integer part include by _mc_adjust_)...
        // use Const.LOG10 for optimization.
        BigDecimal ln10 = nmc.getPrecision()<Const.LOG10.precision() ? Const.LOG10.round(nmc) : log(BigDecimal.TEN, nmc);
        BigDecimal lnx = log(x, nmc);
        return lnx.divide(ln10, mc);
    }
View Full Code Here

                    -7,
                    -2,
                    -5,
                    2,
                    -3 };
                BigDecimal S = broadhurstBBP(2, 1, a, new MathContext(1 + mc.getPrecision()));
                S = S.multiply(new BigDecimal(8));
                S = sqrt(divideRound(S, 3));
                return _dec_round_(S,mc);
            }
        }
        else if (n == 3) {
            /* summation of a series roughly proportional to (7/500)^k. Estimate count
             * of terms to estimate the precision (drop the favorable additional
             * 1/k here): 0.013^k <= 10^(-precision), so k*log10(0.013) <= -precision
             * so k>= precision/1.87.
             */
            int kmax = (int) (mc.getPrecision() / 1.87);
            MathContext mcloc = new MathContext(mc.getPrecision() + 1 + (int) (Math.log10(kmax * 0.693 / 1.098)));
            BigDecimal log3 = multiplyRound(log(new BigDecimal(2), mcloc), 19);

            /* log3 is roughly 1, so absolute and relative error are the same. The
             * result will be divided by 12, so a conservative error is the one
             * already found in mc
             */
            double eps = prec2err(1.098, mc.getPrecision()) / kmax;
            Rational r = new Rational(7153, 524288);
            Rational pk = new Rational(7153, 524288);
            for (int k = 1; ; k++) {
                Rational tmp = pk.divide(k);
                if (tmp.doubleValue() < eps)
                    break;

                /*
                 * how many digits of tmp do we need in the sum?
                 */
                mcloc = new MathContext(err2prec(tmp.doubleValue(), eps));
                BigDecimal c = pk.divide(k).BigDecimalValue(mcloc);
                if (k % 2 != 0)
                    log3 = log3.add(c);
                else
                    log3 = log3.subtract(c);
                pk = pk.multiply(r);
            }
            log3 = divideRound(log3, 12);
            return _dec_round_(log3,mc);
        }
        else if (n == 5) {
            /* summation of a series roughly proportional to (7/160)^k. Estimate count
             * of terms to estimate the precision (drop the favorable additional
             * 1/k here): 0.046^k <= 10^(-precision), so k*log10(0.046) <= -precision
             * so k>= precision/1.33.
             */
            int kmax = (int) (mc.getPrecision() / 1.33);
            MathContext mcloc = new MathContext(mc.getPrecision() + 1 + (int) (Math.log10(kmax * 0.693 / 1.609)));
            BigDecimal log5 = multiplyRound(log(new BigDecimal(2), mcloc), 14);

            /* log5 is roughly 1.6, so absolute and relative error are the same. The
             * result will be divided by 6, so a conservative error is the one
             * already found in mc
             */
            double eps = prec2err(1.6, mc.getPrecision()) / kmax;
            Rational r = new Rational(759, 16384);
            Rational pk = new Rational(759, 16384);
            for (int k = 1; ; k++) {
                Rational tmp = pk.divide(k);
                if (tmp.doubleValue() < eps)
                    break;

                /*
                 * how many digits of tmp do we need in the sum?
                 */
                mcloc = new MathContext(err2prec(tmp.doubleValue(), eps));
                BigDecimal c = pk.divide(k).BigDecimalValue(mcloc);
                log5 = log5.subtract(c);
                pk = pk.multiply(r);
            }
            log5 = divideRound(log5, 6);
            return _dec_round_(log5,mc);
        }
        else if (n == 7) {
            /* summation of a series roughly proportional to (1/8)^k. Estimate count
             * of terms to estimate the precision (drop the favorable additional
             * 1/k here): 0.125^k <= 10^(-precision), so k*log10(0.125) <= -precision
             * so k>= precision/0.903.
             */
            int kmax = (int) (mc.getPrecision() / 0.903);
            MathContext mcloc = new MathContext(mc.getPrecision() + 1 + (int) (Math.log10(kmax * 3 * 0.693 / 1.098)));
            BigDecimal log7 = multiplyRound(log(new BigDecimal(2), mcloc), 3);

            /*
             * log7 is roughly 1.9, so absolute and relative error are the same.
             */
            double eps = prec2err(1.9, mc.getPrecision()) / kmax;
            Rational r = new Rational(1, 8);
            Rational pk = new Rational(1, 8);
            for (int k = 1; ; k++) {
                Rational tmp = pk.divide(k);
                if (tmp.doubleValue() < eps)
                    break;

                /*
                 * how many digits of tmp do we need in the sum?
                 */
                mcloc = new MathContext(err2prec(tmp.doubleValue(), eps));
                BigDecimal c = pk.divide(k).BigDecimalValue(mcloc);
                log7 = log7.subtract(c);
                pk = pk.multiply(r);
            }
            return _dec_round_(log7,mc);

        }

        else if ((n == 10) && (mc.getPrecision() < Const.LOG10.precision()))       // added by l.bruninx, 2012-03-29
                return Const.LOG10.round(mc);                                      // added by l.bruninx, 2012-03-29
       
        else {
            /* At this point one could either forward to the log(BigDecimal) signature (implemented)
             * or decompose n into Ifactors and use an implemenation of all the prime bases.
             * Estimate of the result; convert the mc argument to an  absolute error eps
             * log(n+errn) = log(n)+errn/n = log(n)+eps
             */
            double res = Math.log((double) n);
            double eps = prec2err(res, mc.getPrecision());
            /*
             * errn = eps*n, convert absolute error in result to requirement on absolute error in input
             */
            eps *= n;
            /*
             * Convert this absolute requirement of error in n to a relative error in n
             */
            final MathContext mcloc = new MathContext(1 + err2prec((double) n, eps));
            /* Padd n with a number of zeros to trigger the required accuracy in
             * the standard signature method
             */
            BigDecimal nb = scalePrec(new BigDecimal(n), mcloc);
            return _dec_round_(log(nb),mc);
View Full Code Here

            double eps = prec2err(Math.log(r.doubleValue()), mc.getPrecision());

            /* Convert this further into a requirement of the relative precision in r, given that
             * epsr/r is also the relative precision of r. Add one safety digit.
             */
            MathContext mcloc = new MathContext(1 + err2prec(eps));

            final BigDecimal resul = log(r.BigDecimalValue(mcloc));

            return resul.round(mc);
        }
View Full Code Here

TOP

Related Classes of java.math.MathContext

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.