* @param y
     * @return
     */
    public static BigDecimal powerNoRounding(
            BigDecimal x,
            BigDecimal y) {
        // Deal with special cases
        if (y.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ONE;
        }
        if (y.compareTo(BigDecimal.ONE) == 0) {
            return new BigDecimal(x.toString());
        }
        if (x.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        if (x.compareTo(BigDecimal.ONE) == 0) {
            return BigDecimal.ONE;
        }
        if (x.compareTo(BigDecimal.ZERO) == -1) {
            BigDecimal result = powerNoRounding(
                    x.negate(),
                    y);
            if (isEven(y)) {
                return result.negate();
            } else {
                return result;
            }
        }
        if (y.compareTo(BigDecimal.ZERO) == -1) {
            BigDecimal power = powerNoRounding(
                    x,
                    y.negate());
            BigDecimal result = reciprocalWillBeIntegerReturnBigDecimal(
                    power);
            return result;
        }
        if (y.scale() <= 0) {
            return powerNoRounding(
                    x,
                    y.toBigIntegerExact(),
                    64);
        }
        if (x.compareTo(TWO) == -1) {
            if (y.compareTo(BigDecimal.ONE) == -1) {
                throw new UnsupportedOperationException();
            } else {
                throw new UnsupportedOperationException();
            }
        } else {
            if (y.compareTo(BigDecimal.ONE) == -1) {
                // x > 2 && y < 1
                BigDecimal result = powerExponentLessThanOneNoRounding(
                        x,
                        y);
//                int yScale = y.scale();
//                if (yScale < 9) {
//                    BigInteger yunscaled = y.unscaledValue();
//                    BigDecimal resultToBeRooted = power(
//                            x,
//                            yunscaled,
//                            (int) Math.pow(2, yScale),
//                            decimalPlaces + 2,
//                            a_RoundingMode);
//                    BigDecimal result = rootRoundIfNecessary(
//                            resultToBeRooted,
//                            );
//                    return result;
//                }

//                // Use x^a * y^a = (x * y)^a
//                BigInteger xIntegerPart = x.toBigInteger();
//                BigDecimal result0 = power(
//                        xIntegerPart,
//                        y,
//                        decimalPlaces + 2,
//                    a_RoundingMode);
//                BigDecimal
//               BigDecimal result = powerExponentLessThanOne(
//                    x,
//                    y,
//                    decimalPlaces,
//                    a_RoundingMode);
//            return round(result, decimalPlaces, a_RoundingMode);
                //throw new UnsupportedOperationException();
                return result;
            } else {
                // x > 2 && y > 1
                BigInteger y_BigInteger = y.toBigInteger();
                BigDecimal integerPartResult = powerNoRounding(
                        x,
                        y_BigInteger,
                        256);
                BigDecimal fractionalPartResult = powerNoRounding(
                        x,
                        y.subtract(new BigDecimal(y_BigInteger)));
                BigDecimal result = integerPartResult.multiply(
                        fractionalPartResult);
                return result;
////                
////                if (x.compareTo(BigDecimal.TEN) == 1) {
////                    // A log base 10 x will return greater than one
////                    BigDecimal log10x = log(
////                            10,
////                            x,
////                            decimalPlaces,
////                            a_RoundingMode);
////                    BigDecimal ylog10x = multiplyRoundIfNecessary(
////                            y,
////                            log10x,
////                            decimalPlaces * 2, // Is this safe, or should it be a factor of y
////                            a_RoundingMode);
////                    BigDecimal result = power(
////                            BigDecimal.TEN,
////                            ylog10x,
////                            decimalPlaces,
////                            a_RoundingMode);
////                    return result;
////                } else {
////                    // A log base 2 x will return greater than one
////                    BigDecimal log2x = log(
////                            2,
////                            x,
////                            decimalPlaces,
////                            a_RoundingMode);
////                    BigDecimal ylog2x = multiplyRoundIfNecessary(
////                            y,
////                            log2x,
////                            decimalPlaces * 2, // Is this safe, or should it be a factor of y
////                            a_RoundingMode);
////                    BigDecimal result = power(
////                            TWO,
////                            ylog2x,
////                            decimalPlaces,
////                            a_RoundingMode);
////                    return result;
            }
        }
////        // Check a_Generic_BigDecimal
////        if (a_Generic_BigDecimal == null) {
////            a_Generic_BigDecimal = new Generic_BigDecimal();
////        }
//        BigDecimal result;
//        // Case where y is negative
//        // Case where y is less than one
//        if (y.compareTo(BigDecimal.ONE) == -1) {
//            result = powerExponentLessThanOne(
//                    //a_Generic_BigDecimal,
//                    x,
//                    y,
//                    decimalPlaces,
//                    a_RoundingMode);
//            return round(result, decimalPlaces, a_RoundingMode);
//        }
//        if (y.scale() == 0) {
//            result = power(
//                    x,
//                    y.unscaledValue(),
//                    256,
//                    decimalPlaces,
//                    a_RoundingMode);
//            return round(result, decimalPlaces, a_RoundingMode);
//        }
//
//
////        //Integer part
////        BigDecimal partresult = Generic_BigInteger.power(
////                Generic_BigInteger.Two,
////                ylog2x.intValue(),
////                decimalPlaces,
////                a_RoundingMode);
////
////        // Check tollerance of ylog2x.subtract(new BigDecimal(ylog2x.toBigInteger()))
////
//////        BigDecimal nextPartResult = power(
//////                TWO,
//////                ylog2x.subtract(new BigDecimal(ylog2x.toBigInteger())),
//////                a_Generic_BigDecimal,
//////                decimalPlaces,
//////                a_RoundingMode);
////        result = partresult.multiply(partresult);
//////        result = power(
//////                TWO,
//////                ylog2x,
//////                a_Generic_BigDecimal,
//////                decimalPlaces,
//////                a_RoundingMode);
////        return result;
//
//        //System.out.println("e " + e);
//        BigDecimal lnx;
//        if (x.compareTo(BigDecimal.ONE) == 1) {
//            // decimalPlaces decimal place precision is adequate
//            lnx = log(
//                    a_Generic_BigDecimal.get_E_MinDecimalPlaces(decimalPlaces),
//                    x,
//                    decimalPlaces,
//                    a_RoundingMode);
//        } else {
//            int logPrecision = x.precision() - x.scale() + decimalPlaces;
//            lnx = log(
//                    a_Generic_BigDecimal.get_E_MinDecimalPlaces(decimalPlaces),
//                    x,
//                    logPrecision,
//                    a_RoundingMode);
//        }