import java.math.BigDecimal; import java.io.PrintWriter; public class Exponent { public static void main(String[] args) { PrintWriter pen = new PrintWriter(System.out, true); Exponent exp = new Exponent(); BigDecimal x = new BigDecimal(args[0]); int n = Integer.parseInt(args[1]); long start = System.currentTimeMillis(); // BigDecimal result1 = exp.expt1(x,n); long intermediate = System.currentTimeMillis(); BigDecimal result2 = exp.expt2(x,n); long foo = System.currentTimeMillis(); BigDecimal result3 = exp.expt3(x,n); long bar = System.currentTimeMillis(); // pen.println("For version: " + result1); // pen.println("Recursive version: " + result2); // pen.println("While version: " + result3); pen.println("Difference of results: " + result2.subtract(result3)); // pen.println(" v1 Took: " + (intermediate - start)); pen.println(" v2 Took: " + (foo - intermediate)); pen.println(" v3 Took: " + (bar - foo)); } // main(String[]) public BigDecimal expt1(BigDecimal x, int n) { BigDecimal result = new BigDecimal(1.0); for (int i = 0; i < n ; i++) { result = result.multiply(x); } return result; } // expt1(BigDecimal, int) /** * A seemingly more-efficient method for computing * exponents. However, it is annoyingly recursive. */ public BigDecimal expt2(BigDecimal x, int n) { // Base case: x^0 = 1 if (n == 0) { return new BigDecimal(1.0); } // Recursive x^(2k) = (x^k)*(x^k) else if ((n % 2) == 0) { BigDecimal tmp = expt2(x, n/2); return tmp.multiply(tmp); } // Recursive: x^n = x^(n-1)*x else { return x.multiply(expt2(x,n-1)); } } // expt2(BigDecimal, int) /** * An attempt to rewrite expt2 using a while loop rather * than recursion. */ public BigDecimal expt3(BigDecimal x, int n) { BigDecimal accumulator = new BigDecimal(1); // need to repeatedly reduce the power. Idea: // currentx^currentn * accumulator = originalx^originaln while (n > 0) { // If n is even, divide it by two and multiply x by // itself, using the amazing rule that // (x^n = (x^2)^(n/2)) if ((n % 2) == 0) { // Recursive version: expt3(x.multiply(x), n/2, accumulator); n = n/2; x = x.multiply(x); } // n is even // If n is odd, subtract 1 from it and .. else { // Recursive version: expt3(x, n-1, x.multiply(accumulator)); n = n - 1; accumulator = x.multiply(accumulator); } // n is odd } // while return accumulator; } // expt3(BigDecimal, int) } // class Exponent