Goal: Create a simple calculator. It must be able to add, subtract, multiply, divide, raise to a power, and modulate.
Calculator.java/// Name: Cornelius Eanes /// Period: 5 /// Program Name: Calculator /// File Name: Calculator.java /// Date Finished: May 12, 2016 import java.math.BigDecimal; import java.math.MathContext; import java.util.Scanner; public class Calculator { public static void main(String[] args) { Scanner userIn = new Scanner(System.in); System.out.println("Welcome to Cornelius' Calculator!"); System.out.println("Type \"oper\" for a list of valid operations."); System.out.println("Type \"const\" for a list of valid constants."); System.out.println("Type \"prec\" to toggle the amount of precision."); System.out.println("Type \"quit\" to quit."); String line; do { System.out.print("\n> "); line = userIn.nextLine(); try { if ("oper".equals(line)) { listOperations(); } else if ("const".equals(line)) { listConstants(); } else if ("prec".equals(line)) { changePrecision(); } else if (!"quit".equals(line)) { BigDecimal ans = Operation.parseAndOperate(line); System.out.println("ANS: " + ans); lastAnswer = ans; } } catch (Exception e) { System.out.println("ERROR: " + e.getMessage()); } } while (!"quit".equals(line)); } private static void listOperations() { for (Operation op : Operation.values()) { System.out.println(op.name() + " (" + op.symbol + ")"); } } private static void listConstants() { System.out.println("E - Euler's constant"); System.out.println("PI - Circle circumference-to-diameter ratio"); System.out.print("ANS - Last calculated answer"); if (lastAnswer != null) { System.out.println(" (" + lastAnswer + ")"); } else { System.out.println(); } } private static void changePrecision() { if (ctx.equals(MathContext.DECIMAL32)) { ctx = MathContext.DECIMAL64; } else if (ctx.equals(MathContext.DECIMAL64)) { ctx = MathContext.UNLIMITED; } else { ctx = MathContext.DECIMAL32; } System.out.println("Precision changed to " + ctx.getPrecision()); } private static BigDecimal lastAnswer = null; private static MathContext ctx = MathContext.DECIMAL32; public static BigDecimal getLastAnswer() { return lastAnswer; } public static MathContext getMathContext() { return ctx; } }Operation.java
/// Name: Cornelius Eanes /// Period: 5 /// Program Name: Calculator /// File Name: Operation.java /// Date Finished: May 12, 2016 import java.math.BigDecimal; import java.util.NoSuchElementException; import java.util.Scanner; public enum Operation { ADD('+') { @Override public BigDecimal operate(BigDecimal... nums) { if (nums.length == 2) { return nums[0].add(nums[1]); } return invalidNumArgs(2, nums); } }, SUBTRACT('-') { @Override public BigDecimal operate(BigDecimal... nums) throws IllegalArgumentException { if (nums.length == 2) { return nums[0].subtract(nums[1]); } return invalidNumArgs(2, nums); } }, MULTIPLY('*') { @Override public BigDecimal operate(BigDecimal... nums) throws IllegalArgumentException { if (nums.length == 2) { return nums[0].multiply(nums[1]); } return invalidNumArgs(2, nums); } }, DIVIDE('/') { @Override public BigDecimal operate(BigDecimal... nums) throws IllegalArgumentException { if (nums.length == 2) { return nums[0].divide(nums[1], BigDecimal.ROUND_HALF_UP); } return invalidNumArgs(2, nums); } }, MOD('%') { @Override public BigDecimal operate(BigDecimal... nums) throws IllegalArgumentException { if (nums.length == 2) { return nums[0].remainder(nums[1]); } return invalidNumArgs(2, nums); } }, EXPONENT('^') { @Override public BigDecimal operate(BigDecimal... nums) throws IllegalArgumentException { if (nums.length == 2) { return nums[0].pow(nums[1].intValue()); } return invalidNumArgs(2, nums); } }; public final char symbol; Operation(char symbol) { this.symbol = symbol; } public abstract BigDecimal operate(BigDecimal... nums) throws IllegalArgumentException; static BigDecimal invalidNumArgs(int required, BigDecimal[] nums) { throw new IllegalArgumentException("Requires " + required + " arguments, found " + nums.length); } public static Operation getFromSymbol(char c) { for (Operation op : Operation.values()) { if (op.symbol == c) { return op; } } return null; } public static BigDecimal parseAndOperate(String s) { Scanner scanner = new Scanner(s); String o1 = null, o2 = null, o3; BigDecimal n1 = null, n2 = null; Operation op = null; try { o1 = scanner.next(); o2 = scanner.next(); o3 = scanner.next(); n1 = parseDecimal(o1); op = getFromSymbol(o2.charAt(0)); if (op == null) { throw new IllegalArgumentException("Invalid operand symbol: " + o2); } n2 = parseDecimal(o3); return op.operate(n1, n2).round(Calculator.getMathContext()); } catch (NoSuchElementException e) { throw new RuntimeException("Requires 3 arguments: [num] [operand] [num]"); } catch (NumberFormatException e) { throw new RuntimeException("Invalid number: " + (n1 == null ? o1 : o2)); } } private static BigDecimal BD_E = new BigDecimal(Math.E), BD_PI = new BigDecimal(Math.PI); private static BigDecimal parseDecimal(String s) throws IllegalArgumentException { if ("e".equalsIgnoreCase(s)) { return BD_E; } else if ("pi".equalsIgnoreCase(s)) { return BD_PI; } else if ("ans".equalsIgnoreCase(s)) { return Calculator.getLastAnswer(); } try { return new BigDecimal(s); } catch (NumberFormatException e) { throw new IllegalArgumentException("Not a valid constant nor number: " + s); } } }