// // file: Calculator.java // // (C) 1997-1999 Beta Nine. All Rights Reserved. // written by sven@beta9.be - http://www.beta9.be // $Id: Calculator.java,v 1.1 2005/10/24 14:47:49 cvs Exp $ // package wonka.test; public class Calculator { // I model the internal workings of a calculator, not the actual UI. // You can operate me like a classical calcualtor, // i.e. my public methods represent the calculator keys'. // My accumulator is the value the user sees. // internal structure // holds the working number (which is being edited) private double accumulatorValue; // holds other operand (previous accumulator) private double transientValue; // holds the current operator private int operatorCode; // used in decimal number input private int trailingDigits; // used in decimal number input private boolean startNewDigit; // operator code constants private final static int NO_OPERATOR = 0; private final static int DIVIDE_OPERATOR = 1; private final static int MULTIPLY_OPERATOR = 2; private final static int PLUS_OPERATOR = 3; private final static int SUBTRACT_OPERATOR = 4; // initialize public Calculator() { accumulatorValue = transientValue = 0.0; operatorCode = NO_OPERATOR; trailingDigits = 0; startNewDigit = true; } // accessing the accumulator public double accumulator() { return accumulatorValue; } // accessing the number of trailingDigits public int trailingDigits() { return trailingDigits; } // key: / public void divideOperator() { acceptOperator(DIVIDE_OPERATOR); } // key: * public void multiplyOperator() { acceptOperator(MULTIPLY_OPERATOR); } // key: + public void plusOperator() { acceptOperator(PLUS_OPERATOR); } // key: - public void subtractOperator() { acceptOperator(SUBTRACT_OPERATOR); } // key: 0 public void zero() { newDigit(0); } // key: 1 public void one() { newDigit(1); } // key: 2 public void two() { newDigit(2); } // key: 3 public void three() { newDigit(3); } // key: 4 public void four() { newDigit(4); } // key: 5 public void five() { newDigit(5); } // key: 6 public void six() { newDigit(6); } // key: 7 public void seven() { newDigit(7); } // key: 8 public void eight() { newDigit(8); } // key: 9 public void nine() { newDigit(9); } // key: . public void dot() { if (startNewDigit) { accumulatorValue = 0.0; startNewDigit = false; } if (trailingDigits == 0) { trailingDigits = 1; } } // key: C public void clear() { accumulatorValue = transientValue = 0.0; operatorCode = NO_OPERATOR; trailingDigits = 0; startNewDigit = true; } // key: = // key: ENTER public void enter() { try { switch (operatorCode) { case NO_OPERATOR: break; case PLUS_OPERATOR: accumulatorValue = transientValue + accumulatorValue; break; case SUBTRACT_OPERATOR:; accumulatorValue = transientValue - accumulatorValue; break; case MULTIPLY_OPERATOR:; accumulatorValue = transientValue * accumulatorValue; break; case DIVIDE_OPERATOR:; accumulatorValue = transientValue / accumulatorValue; break; } } catch (ArithmeticException e) { accumulatorValue = 0; } finally { transientValue = 0.0; operatorCode = NO_OPERATOR; trailingDigits = 0; startNewDigit = true; } } // key: +/- public void invert() { accumulatorValue = - accumulatorValue; } // key: 1/x public void reciprocal() { if (accumulatorValue == 0) return; accumulatorValue = 1 / accumulatorValue; startNewDigit = true; trailingDigits = 0; } // a new operator is entered private void acceptOperator(int code) { if (operatorCode == NO_OPERATOR) { transientValue = accumulatorValue; startNewDigit = true; } else { // user is cascading operations enter(); } operatorCode = code; trailingDigits = 0; } // a new digit is entered private void newDigit(int digit) { if (startNewDigit) { transientValue = accumulatorValue; startNewDigit = false; accumulatorValue = (double)digit; } else { boolean negative = false; if (accumulatorValue < 0) { accumulatorValue = - accumulatorValue; negative = true; } if (trailingDigits == 0) { accumulatorValue = accumulatorValue * 10 + (double)digit; } else { accumulatorValue += (double)digit / Math.pow(10, (double)trailingDigits); trailingDigits++; } if (negative) accumulatorValue = - accumulatorValue; } } }