Example usage for java.lang ArithmeticException ArithmeticException

List of usage examples for java.lang ArithmeticException ArithmeticException

Introduction

In this page you can find the example usage for java.lang ArithmeticException ArithmeticException.

Prototype

public ArithmeticException(String s) 

Source Link

Document

Constructs an ArithmeticException with the specified detail message.

Usage

From source file:Rotation.java

/** Compute the angular separation between two vectors.
 * <p>This method computes the angular separation between two
 * vectors using the dot product for well separated vectors and the
 * cross product for almost aligned vectors. This allow to have a
 * good accuracy in all cases, even for vectors very close to each
 * other.</p>//from   w  w w  .  j a  v a2  s .  c  o m
 * @param v1 first vector
 * @param v2 second vector
 * @return angular separation between v1 and v2
 * @exception ArithmeticException if either vector has a null norm
 */
public static double angle(Vector3D v1, Vector3D v2) {

    double normProduct = v1.getNorm() * v2.getNorm();
    if (normProduct == 0) {
        throw new ArithmeticException("null norm");
    }

    double dot = dotProduct(v1, v2);
    double threshold = normProduct * 0.9999;
    if ((dot < -threshold) || (dot > threshold)) {
        // the vectors are almost aligned, compute using the sine
        Vector3D v3 = crossProduct(v1, v2);
        if (dot >= 0) {
            return Math.asin(v3.getNorm() / normProduct);
        }
        return Math.PI - Math.asin(v3.getNorm() / normProduct);
    }

    // the vectors are sufficiently separated to use the cosine
    return Math.acos(dot / normProduct);

}

From source file:net.pms.util.Rational.java

/**
 * Converts this {@link Rational} to a {@link BigDecimal}. This may involve
 * rounding. The conversion is limited to 100 decimals and uses
 * {@link RoundingMode#HALF_EVEN}./* www .j  a  va2 s .  c o m*/
 * <p>
 * For explicit control over the conversion, use one of the overloaded
 * methods.
 *
 * @return This {@link Rational} converted to a {@link BigDecimal}.
 * @throws ArithmeticException If this is {@code NaN} or infinite.
 *
 * @see #bigDecimalValue(MathContext)
 * @see #bigDecimalValue(RoundingMode)
 * @see #bigDecimalValue(int, RoundingMode)
 */
@Nonnull
public BigDecimal bigDecimalValue() {
    if (isNaN()) {
        throw new ArithmeticException("Impossible to express NaN as BigDecimal");
    }
    if (isInfinite()) {
        throw new ArithmeticException("Impossible to express infinity as BigDecimal");
    }

    if (BigInteger.ONE.equals(reducedDenominator)) {
        return new BigDecimal(reducedNumerator);
    }
    return new BigDecimal(reducedNumerator).divide(new BigDecimal(reducedDenominator), 100,
            RoundingMode.HALF_EVEN);
}

From source file:net.pms.util.Rational.java

/**
 * Converts this {@link Rational} to a {@link BigDecimal}. This may involve
 * rounding. The conversion is limited to 100 decimals and uses
 * {@code roundingMode}./* w w w . ja va  2s  .  co m*/
 *
 * @param roundingMode the {@link RoundingMode} to apply.
 * @return This {@link Rational} converted to a {@link BigDecimal}.
 * @throws ArithmeticException If this is {@code NaN} or infinite or if
 *             {@code roundingMode} is {@link RoundingMode#UNNECESSARY} and
 *             the specified scale is insufficient to represent the result
 *             of the division exactly.
 *
 * @see #bigDecimalValue()
 * @see #bigDecimalValue(MathContext)
 * @see #bigDecimalValue(int, RoundingMode)
 */
@Nonnull
public BigDecimal bigDecimalValue(RoundingMode roundingMode) {
    if (isNaN()) {
        throw new ArithmeticException("Impossible to express NaN as BigDecimal");
    }
    if (isInfinite()) {
        throw new ArithmeticException("Impossible to express infinity as BigDecimal");
    }

    if (BigInteger.ONE.equals(reducedDenominator)) {
        return new BigDecimal(reducedNumerator);
    }
    return new BigDecimal(reducedNumerator).divide(new BigDecimal(reducedDenominator), 100, roundingMode);
}

From source file:net.pms.util.Rational.java

/**
 * Converts this {@link Rational} to a {@link BigDecimal}. This may involve
 * rounding.//  w  w  w.jav a2 s  . com
 * <p>
 * Use {@code scale == 0} and
 * {@code roundingMode == RoundingMode.UNNECESSARY} to achieve absolute
 * precision. This will throw an {@link ArithmeticException} if the exact
 * quotient cannot be represented (because it has a non-terminating decimal
 * expansion).
 *
 * @param scale the scale of the {@link BigDecimal} quotient to be returned.
 * @param roundingMode the {@link RoundingMode} to apply.
 * @return This {@link Rational} converted to a {@link BigDecimal}.
 * @throws ArithmeticException If this is {@code NaN} or infinite or if
 *             {@code roundingMode} is {@link RoundingMode#UNNECESSARY} and
 *             the specified scale is insufficient to represent the result
 *             of the division exactly.
 *
 * @see #bigDecimalValue()
 * @see #bigDecimalValue(MathContext)
 * @see #bigDecimalValue(RoundingMode)
 */
@Nonnull
public BigDecimal bigDecimalValue(int scale, RoundingMode roundingMode) {
    if (isNaN()) {
        throw new ArithmeticException("Impossible to express NaN as BigDecimal");
    }
    if (isInfinite()) {
        throw new ArithmeticException("Impossible to express infinity as BigDecimal");
    }

    if (BigInteger.ONE.equals(reducedDenominator)) {
        return new BigDecimal(reducedNumerator);
    }
    return new BigDecimal(reducedNumerator).divide(new BigDecimal(reducedDenominator), scale, roundingMode);
}

From source file:org.nd4j.linalg.util.BigDecimalMath.java

/**
 * The inverse hyperbolic cosine.//  w ww .  jav a 2s. c o  m
 *
 * @param x The argument.
 * @return The arccosh(x) .
 */
static public BigDecimal acosh(final BigDecimal x) {
    if (x.compareTo(BigDecimal.ONE) < 0) {
        throw new ArithmeticException("Out of range argument cosh " + x.toString());
    } else if (x.compareTo(BigDecimal.ONE) == 0) {
        return BigDecimal.ZERO;
    } else {
        BigDecimal xhighpr = scalePrec(x, 2);
        /* arccosh(x) = log(x+sqrt(x^2-1))
         */
        BigDecimal logx = log(sqrt(xhighpr.pow(2).subtract(BigDecimal.ONE)).add(xhighpr));
        /* The absolute error in arcsinh x is err(x)/sqrt(x^2-1)
         */

        double xDbl = x.doubleValue();

        double eps = 0.5 * x.ulp().doubleValue() / Math.sqrt(xDbl * xDbl - 1.);
        MathContext mc = new MathContext(err2prec(logx.doubleValue(), eps));

        return logx.round(mc);

    }
}

From source file:org.nd4j.linalg.util.BigDecimalMath.java

/**
 * Riemann zeta function./*w  w w .  ja  v a2  s .  co m*/
 *
 * @param n  The positive integer argument.
 *           32
 * @param mc Specification of the accuracy of the result.
 * @return zeta(n).
 */
static public BigDecimal zeta(final int n, final MathContext mc) {
    if (n <= 0) {
        throw new ProviderException("Unimplemented zeta at negative argument " + n);
    }

    if (n == 1) {
        throw new ArithmeticException("Pole at zeta(1) ");
    }

    if (n % 2 == 0) {
        /* Even indices. Abramowitz-Stegun 23.2.16. Start with 2^(n-1)*B(n)/n!
         */
        Rational b = (new Bernoulli()).at(n).abs();
        b = b.divide((new Factorial()).at(n));
        b = b.multiply(BigInteger.ONE.shiftLeft(n - 1));
        /* to be multiplied by pi^n. Absolute error in the result of pi^n is n times
         * error in pi times pi^(n-1). Relative error is n*error(pi)/pi, requested by mc.
         * Need one more digit in pi if n=10, two digits if n=100 etc, and add one extra digit.
         */
        MathContext mcpi = new MathContext(mc.getPrecision() + (int) (Math.log10(10.0 * n)));
        final BigDecimal piton = pi(mcpi).pow(n, mc);

        return multiplyRound(piton, b);

    } else if (n == 3) {
        /* Broadhurst BBP \protect\vrule width0pt\protect\href{http://arxiv.org/abs/math/9803067}{arXiv:math/9803067}
         * Error propagation: S31 is roughly 0.087, S33 roughly 0.131
         */
        int[] a31 = { 1, -7, -1, 10, -1, -7, 1, 0 };

        int[] a33 = { 1, 1, -1, -2, -1, 1, 1, 0 };
        BigDecimal S31 = broadhurstBBP(3, 1, a31, mc);
        BigDecimal S33 = broadhurstBBP(3, 3, a33, mc);
        S31 = S31.multiply(new BigDecimal(48));
        S33 = S33.multiply(new BigDecimal(32));

        return S31.add(S33).divide(new BigDecimal(7), mc);

    } else if (n == 5) {
        /* Broadhurst BBP \protect\vrule width0pt\protect\href{http://arxiv.org/abs/math/9803067}{arXiv:math/9803067}
         * Error propagation: S51 is roughly -11.15, S53 roughly 22.165, S55 is roughly 0.031
         * 9*2048*S51/6265 = -3.28. 7*2038*S53/61651= 5.07. 738*2048*S55/61651= 0.747.
         * The result is of the order 1.03, so we add 2 digits to S51 and S52 and one digit to S55.
         */
        int[] a51 = { 31, -1614, -31, -6212, -31, -1614, 31, 74552 };

        int[] a53 = { 173, 284, -173, -457, -173, 284, 173, -111 };

        int[] a55 = { 1, 0, -1, -1, -1, 0, 1, 1 };
        BigDecimal S51 = broadhurstBBP(5, 1, a51, new MathContext(2 + mc.getPrecision()));
        BigDecimal S53 = broadhurstBBP(5, 3, a53, new MathContext(2 + mc.getPrecision()));
        BigDecimal S55 = broadhurstBBP(5, 5, a55, new MathContext(1 + mc.getPrecision()));
        S51 = S51.multiply(new BigDecimal(18432));
        S53 = S53.multiply(new BigDecimal(14336));
        S55 = S55.multiply(new BigDecimal(1511424));

        return S51.add(S53).subtract(S55).divide(new BigDecimal(62651), mc);

    } else {
        /* Cohen et al Exp Math 1 (1) (1992) 25
         */
        Rational betsum = new Rational();
        Bernoulli bern = new Bernoulli();
        Factorial fact = new Factorial();

        for (int npr = 0; npr <= (n + 1) / 2; npr++) {
            Rational b = bern.at(2 * npr).multiply(bern.at(n + 1 - 2 * npr));
            b = b.divide(fact.at(2 * npr)).divide(fact.at(n + 1 - 2 * npr));
            b = b.multiply(1 - 2 * npr);

            if (npr % 2 == 0) {
                betsum = betsum.add(b);
            } else {
                betsum = betsum.subtract(b);
            }

        }
        betsum = betsum.divide(n - 1);
        /* The first term, including the facor (2pi)^n, is essentially most
         * of the result, near one. The second term below is roughly in the range 0.003 to 0.009.
         * So the precision here is matching the precisionn requested by mc, and the precision
         * requested for 2*pi is in absolute terms adjusted.
         */
        MathContext mcloc = new MathContext(2 + mc.getPrecision() + (int) (Math.log10((double) (n))));
        BigDecimal ftrm = pi(mcloc).multiply(new BigDecimal(2));
        ftrm = ftrm.pow(n);

        ftrm = multiplyRound(ftrm, betsum.BigDecimalValue(mcloc));
        BigDecimal exps = new BigDecimal(0);
        /* the basic accuracy of the accumulated terms before multiplication with 2
         */

        double eps = Math.pow(10., -mc.getPrecision());

        if (n % 4 == 3) {
            /* since the argument n is at least 7 here, the drop
             * of the terms is at rather constant pace at least 10^-3, for example
             * 0.0018, 0.2e-7, 0.29e-11, 0.74e-15 etc for npr=1,2,3.... We want 2 times these terms
             * fall below eps/10.
             */
            int kmax = mc.getPrecision() / 3;
            eps /= kmax;
            /* need an error of eps for 2/(exp(2pi)-1) = 0.0037
             * The absolute error is 4*exp(2pi)*err(pi)/(exp(2pi)-1)^2=0.0075*err(pi)
             */
            BigDecimal exp2p = pi(new MathContext(3 + err2prec(3.14, eps / 0.0075)));
            exp2p = exp(exp2p.multiply(new BigDecimal(2)));
            BigDecimal c = exp2p.subtract(BigDecimal.ONE);
            exps = divideRound(1, c);

            for (int npr = 2; npr <= kmax; npr++) {
                /* the error estimate above for npr=1 is the worst case of
                 * the absolute error created by an error in 2pi. So we can
                 * safely re-use the exp2p value computed above without
                 * reassessment of its error.
                 */
                c = powRound(exp2p, npr).subtract(BigDecimal.ONE);
                c = multiplyRound(c, (new BigInteger("" + npr)).pow(n));
                c = divideRound(1, c);
                exps = exps.add(c);

            }
        } else {
            /* since the argument n is at least 9 here, the drop
             * of the terms is at rather constant pace at least 10^-3, for example
             * 0.0096, 0.5e-7, 0.3e-11, 0.6e-15 etc. We want these terms
             * fall below eps/10.
             */
            int kmax = (1 + mc.getPrecision()) / 3;
            eps /= kmax;
            /* need an error of eps for 2/(exp(2pi)-1)*(1+4*Pi/8/(1-exp(-2pi)) = 0.0096
             * at k=7 or = 0.00766 at k=13 for example.
             * The absolute error is 0.017*err(pi) at k=9, 0.013*err(pi) at k=13, 0.012 at k=17
             */
            BigDecimal twop = pi(new MathContext(3 + err2prec(3.14, eps / 0.017)));
            twop = twop.multiply(new BigDecimal(2));
            BigDecimal exp2p = exp(twop);
            BigDecimal c = exp2p.subtract(BigDecimal.ONE);
            exps = divideRound(1, c);
            c = BigDecimal.ONE.subtract(divideRound(1, exp2p));
            c = divideRound(twop, c).multiply(new BigDecimal(2));
            c = divideRound(c, n - 1).add(BigDecimal.ONE);
            exps = multiplyRound(exps, c);

            for (int npr = 2; npr <= kmax; npr++) {
                c = powRound(exp2p, npr).subtract(BigDecimal.ONE);
                c = multiplyRound(c, (new BigInteger("" + npr)).pow(n));
                BigDecimal d = divideRound(1, exp2p.pow(npr));
                d = BigDecimal.ONE.subtract(d);
                d = divideRound(twop, d).multiply(new BigDecimal(2 * npr));
                d = divideRound(d, n - 1).add(BigDecimal.ONE);
                d = divideRound(d, c);
                exps = exps.add(d);

            }
        }
        exps = exps.multiply(new BigDecimal(2));

        return ftrm.subtract(exps, mc);

    }
}

From source file:net.pms.util.Rational.java

/**
 * Used internally to find by which factor to multiply the reduced
 * numerators when comparing two {@link Rational}s.
 *
 * @param other the {@link Rational} to which this {@link Rational}'s value
 *            is to be compared.//www .j ava 2s .co  m
 * @return An array of {@link BigInteger} multipliers.
 * @throws ArithmeticException if either part is {@code NaN} or infinite.
 */
@Nonnull
protected BigInteger[] getMultipliers(@Nonnull Rational other) {
    if (isNaN() || isInfinite() || other.isNaN() || other.isInfinite()) {
        throw new ArithmeticException("Can't calculate multipliers for NaN or infinity");
    }
    BigInteger[] result = new BigInteger[2];
    BigInteger lcm = calculateLeastCommonMultiple(reducedDenominator, other.reducedDenominator);
    result[0] = lcm.divide(reducedDenominator);
    result[1] = lcm.divide(other.reducedDenominator);
    return result;
}

From source file:net.pms.util.Rational.java

/**
 * Calculates the greatest common divisor for two {@link Long}s using
 * "binary GDC" with some optimizations borrowed from
 * {@link org.apache.commons.lang.math.Fraction#greatestCommonDivisor}.
 *
 * @param u the first number./* ww w .j  a v a  2 s  .  co  m*/
 * @param v the second number.
 * @return The GDC, always 1 or greater.
 * @throws ArithmeticException if GDC is greater than {@link Long#MAX_VALUE}.
 */
public static long calculateGreatestCommonDivisor(long u, long v) {
    if (Math.abs(u) <= 1 || Math.abs(v) <= 1) {
        return 1;
    }
    // keep u and v negative, as negative integers range down to
    // -2^63, while positive numbers can only be as large as 2^63-1.
    if (u > 0) {
        u = -u;
    }
    if (v > 0) {
        v = -v;
    }
    int k = 0;
    while ((u & 1) == 0 && (v & 1) == 0 && k < 63) {
        u >>= 1;
        v >>= 1;
        k++;
    }
    if (k == 63) {
        throw new ArithmeticException("Overflow: gcd is 2^63");
    }
    long t = ((u & 1) == 1) ? v : -(u >> 1);
    do {
        while ((t & 1) == 0) {
            t >>= 1;
        }
        if (t > 0) {
            u = -t;
        } else {
            v = t;
        }
        t = (v - u) >> 1;
    } while (t != 0);

    return -u * (1 << k);
}

From source file:ffx.potential.nonbonded.ParticleMeshEwald.java

/**
 * Converge the SCF using Successive Over-Relaxation (SOR).
 *///w  w w .j av  a 2  s  . c  o m
private int scfBySOR(boolean print, long startTime) {
    long directTime = System.nanoTime() - startTime;
    /**
     * A request of 0 SCF cycles simplifies mutual polarization to direct
     * polarization.
     */
    StringBuilder sb = null;
    if (print) {
        sb = new StringBuilder("\n Self-Consistent Field\n" + " Iter  RMS Change (Debye)  Time\n");
    }
    int completedSCFCycles = 0;
    int maxSCFCycles = 1000;
    double eps = 100.0;
    double previousEps;
    boolean done = false;
    while (!done) {
        long cycleTime = -System.nanoTime();
        try {
            if (aewald > 0.0) {
                reciprocalSpace.splineInducedDipoles(inducedDipole, inducedDipoleCR, use);
            }
            sectionTeam.execute(inducedDipoleFieldRegion);
            if (aewald > 0.0) {
                reciprocalSpace.computeInducedPhi(cartesianDipolePhi, cartesianDipolePhiCR);
            }

            if (generalizedKirkwoodTerm) {
                /**
                 * GK field.
                 */
                gkEnergyTotal = -System.nanoTime();
                generalizedKirkwood.computeInducedGKField();
                gkEnergyTotal += System.nanoTime();
                logger.fine(String.format(" Computed GK induced field %8.3f (sec)", gkEnergyTotal * 1.0e-9));
            }
            parallelTeam.execute(sorRegion);
            if (nSymm > 1) {
                parallelTeam.execute(expandInducedDipolesRegion);
            }
        } catch (Exception e) {
            String message = "Exception computing mutual induced dipoles.";
            logger.log(Level.SEVERE, message, e);
        }
        completedSCFCycles++;
        previousEps = eps;
        eps = sorRegion.getEps();
        eps = MultipoleType.DEBYE * sqrt(eps / (double) nAtoms);
        cycleTime += System.nanoTime();
        if (print) {
            sb.append(format(" %4d     %15.10f %7.4f\n", completedSCFCycles, eps, cycleTime * toSeconds));
        }
        /**
         * If the RMS Debye change increases, fail the SCF process.
         */
        if (eps > previousEps) {
            if (sb != null) {
                logger.warning(sb.toString());
            }
            String message = format("Fatal SCF convergence failure: (%10.5f > %10.5f)\n", eps, previousEps);
            throw new ArithmeticException(message);
        }
        /**
         * The SCF should converge well before the max iteration check.
         * Otherwise, fail the SCF process.
         */
        if (completedSCFCycles >= maxSCFCycles) {
            if (sb != null) {
                logger.warning(sb.toString());
            }
            String message = format("Maximum SCF iterations reached: (%d)\n", completedSCFCycles);
            throw new ArithmeticException(message);
        }
        /**
         * Check if the convergence criteria has been achieved.
         */
        if (eps < poleps) {
            done = true;
        }
    }
    if (print) {
        sb.append(format(" Direct:                  %7.4f\n", toSeconds * directTime));
        startTime = System.nanoTime() - startTime;
        sb.append(format(" Total:                   %7.4f", startTime * toSeconds));
        logger.info(sb.toString());
    }
    return completedSCFCycles;
}

From source file:org.nd4j.linalg.util.BigDecimalMath.java

/**
 * Riemann zeta function.//from  ww  w. jav a  2  s .  com
 *
 * @param n The positive integer argument.
 * @return zeta(n)-1.
 */
static public double zeta1(final int n) {
    /* precomputed static table in double precision
     */
    final double[] zmin1 = { 0., 0., 6.449340668482264364724151666e-01, 2.020569031595942853997381615e-01,
            8.232323371113819151600369654e-02, 3.692775514336992633136548646e-02,
            1.734306198444913971451792979e-02, 8.349277381922826839797549850e-03,
            4.077356197944339378685238509e-03, 2.008392826082214417852769232e-03,
            9.945751278180853371459589003e-04, 4.941886041194645587022825265e-04,
            2.460865533080482986379980477e-04, 1.227133475784891467518365264e-04,
            6.124813505870482925854510514e-05, 3.058823630702049355172851064e-05,
            1.528225940865187173257148764e-05, 7.637197637899762273600293563e-06,
            3.817293264999839856461644622e-06, 1.908212716553938925656957795e-06,
            9.539620338727961131520386834e-07, 4.769329867878064631167196044e-07,
            2.384505027277329900036481868e-07, 1.192199259653110730677887189e-07,
            5.960818905125947961244020794e-08, 2.980350351465228018606370507e-08,
            1.490155482836504123465850663e-08, 7.450711789835429491981004171e-09,
            3.725334024788457054819204018e-09, 1.862659723513049006403909945e-09,
            9.313274324196681828717647350e-10, 4.656629065033784072989233251e-10,
            2.328311833676505492001455976e-10, 1.164155017270051977592973835e-10,
            5.820772087902700889243685989e-11, 2.910385044497099686929425228e-11,
            1.455192189104198423592963225e-11, 7.275959835057481014520869012e-12,
            3.637979547378651190237236356e-12, 1.818989650307065947584832101e-12,
            9.094947840263889282533118387e-13, 4.547473783042154026799112029e-13,
            2.273736845824652515226821578e-13, 1.136868407680227849349104838e-13,
            5.684341987627585609277182968e-14, 2.842170976889301855455073705e-14,
            1.421085482803160676983430714e-14, 7.105427395210852712877354480e-15,
            3.552713691337113673298469534e-15, 1.776356843579120327473349014e-15,
            8.881784210930815903096091386e-16, 4.440892103143813364197770940e-16,
            2.220446050798041983999320094e-16, 1.110223025141066133720544570e-16,
            5.551115124845481243723736590e-17, 2.775557562136124172581632454e-17,
            1.387778780972523276283909491e-17, 6.938893904544153697446085326e-18,
            3.469446952165922624744271496e-18, 1.734723476047576572048972970e-18,
            8.673617380119933728342055067e-19, 4.336808690020650487497023566e-19,
            2.168404344997219785013910168e-19, 1.084202172494241406301271117e-19,
            5.421010862456645410918700404e-20, 2.710505431223468831954621312e-20,
            1.355252715610116458148523400e-20, 6.776263578045189097995298742e-21,
            3.388131789020796818085703100e-21, 1.694065894509799165406492747e-21,
            8.470329472546998348246992609e-22, 4.235164736272833347862270483e-22,
            2.117582368136194731844209440e-22, 1.058791184068023385226500154e-22,
            5.293955920339870323813912303e-23, 2.646977960169852961134116684e-23,
            1.323488980084899080309451025e-23, 6.617444900424404067355245332e-24,
            3.308722450212171588946956384e-24, 1.654361225106075646229923677e-24,
            8.271806125530344403671105617e-25, 4.135903062765160926009382456e-25,
            2.067951531382576704395967919e-25, 1.033975765691287099328409559e-25,
            5.169878828456431320410133217e-26, 2.584939414228214268127761771e-26,
            1.292469707114106670038112612e-26, 6.462348535570531803438002161e-27,
            3.231174267785265386134814118e-27, 1.615587133892632521206011406e-27,
            8.077935669463162033158738186e-28, 4.038967834731580825622262813e-28,
            2.019483917365790349158762647e-28, 1.009741958682895153361925070e-28,
            5.048709793414475696084771173e-29, 2.524354896707237824467434194e-29,
            1.262177448353618904375399966e-29, 6.310887241768094495682609390e-30,
            3.155443620884047239109841220e-30, 1.577721810442023616644432780e-30,
            7.888609052210118073520537800e-31 };

    if (n <= 0) {
        throw new ProviderException("Unimplemented zeta at negative argument " + n);
    }

    if (n == 1) {
        throw new ArithmeticException("Pole at zeta(1) ");
    }

    if (n < zmin1.length) /* look it up if available */ {
        return zmin1[n];
    } else {
        /* Result is roughly 2^(-n), desired accuracy 18 digits. If zeta(n) is computed, the equivalent accuracy
         * in relative units is higher, because zeta is around 1.
         */
        double eps = 1.e-18 * Math.pow(2., (double) (-n));
        MathContext mc = new MathContext(err2prec(eps));

        return zeta(n, mc).subtract(BigDecimal.ONE).doubleValue();

    }
}