public static BigDecimal rootNoRounding(
            BigDecimal x,
            int root) {
        // Deal with special cases
        if (x.compareTo(BigDecimal.ZERO) == -1) {
            throw new IllegalArgumentException(
                    "x < 0 in " + Generic_BigDecimal.class
                    + ".root(BigDecimal,int,int,RoundingMode)");
        }
        if (x.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        if (x.compareTo(BigDecimal.ONE) == 0) {
            return BigDecimal.ONE;
        }
        if (root == 0) {
            throw new IllegalArgumentException(
                    "root = 0 in " + Generic_BigDecimal.class
                    + ".root(BigDecimal,int,int,RoundingMode)");
        }
        if (root == 1) {
            BigDecimal result = new BigDecimal(x.toString());
            return result;
        }
        // The current (Java6) limit for n in x.pow(n)
        // for BigDecimal x and int n is
        // -999999999 < n < 999999999
        if (root >= 999999999) {
//            Generic_BigDecimal a_Generic_BigDecimal =
//                    new Generic_BigDecimal();
            BigDecimal result = rootNoRounding(
                    x,
                    BigInteger.valueOf(root));
            return result;
            //return round(result, decimalPlaces, a_RoundingMode);
        }
        if (x.compareTo(BigDecimal.ONE) == -1) {
            int xscale = x.scale();
            // This is thought to be an optimisation for a large x.scale()
            // a faster way is needed! This may generally be generally 
            // faster anyway but some tests are needed to be sure.
            int rootLength = Integer.toString(root).length();
            if (xscale < 10) {
                BigDecimal numeratorUnrooted = new BigDecimal(x.unscaledValue());
                //int precisionMinusScale = xprecision - xscale;
                BigDecimal denominatorUnrooted = new BigDecimal(BigInteger.ONE, (-1 * xscale));
                BigDecimal numerator = rootNoRounding(
                        numeratorUnrooted,
                        root);
                BigDecimal denominator = rootNoRounding(
                        denominatorUnrooted,
                        root);
                BigDecimal result = divideNoRounding(
                        numerator,
                        denominator);
                return result;
            } else {
                BigDecimal result = rootLessThanOneNoRounding(
                        x,
                        root);
                return result;
            }
        }
        BigInteger root_BigInteger = BigInteger.valueOf(root);
        BigDecimal result;// = BigDecimal.ONE;
        int rootInitialisationMaxite = 10;
        result = rootInitialisationNoRounding(
                x,
                root_BigInteger,
                rootInitialisationMaxite);
        //int newtonRaphsonMaxite = 100;
        result = newtonRaphsonNoRounding(
                x,
                result,
                root_BigInteger);
        return result;
    }