package polarDust.calculator; /* * Copyright (c) 1996 Sorin Lazareanu, All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL purposes and without * fee is hereby granted provided that this copyright notice * appears in all copies. * */ /** * * This class is an equivalent of a microprocessor in a calculator (minus the * display logic). It executes commands and is capable of sending messages * to a display unit (panel). * Logic organization:
* 2 number registers (double): R1, R2, * 1 memory register (double): RM. * * This class can be further broken down into:
* a Command Control Unit (CCU),
* an Arithmetic and Logic Unit (ALU) and
* Registers * *

* The source code. * * @version 0.9, 1996.06.04 * @author Sorin Lazareanu */ public class Processor01 implements CalcCPU, CalcConstants { boolean bDigits; boolean bDecimalPoint; boolean bUnary; double dReg1, dReg2, dRegM; int iOpReg, iDecPlaces = 0; long lDecimalFactor = 1; CalcDisplay display; /** * Creates a new Processor01 object. Uses a display. * @see CalcDisplay */ public Processor01(CalcDisplay aDisplay) { display = aDisplay; c(); } /** * Performs the calculations for a digit input. * @param iDigit 0...9 */ public void digit(int iDigit) { double dBufferReg = dReg1; if (!display.isError()) { if (!bDigits) { dReg2 = dReg1; dBufferReg = 0d; opRegAssign(iOpReg); }; if (bDecimalPoint) { if (lDecimalFactor <= display.maxDigitsFactor()) { if (dBufferReg >= 0d) dBufferReg = dBufferReg + iDigit/(double)lDecimalFactor; else dBufferReg = dBufferReg - iDigit/(double)lDecimalFactor; lDecimalFactor *= 10; iDecPlaces += 1; }; } else { if (dBufferReg >= 0d) dBufferReg = dBufferReg * 10d + iDigit; else dBufferReg = dBufferReg * 10d - iDigit; iDecPlaces = 0; }; reg1ShowWithDecimals(dBufferReg, iDecPlaces); bDigits = true; bDecimalPoint = bDecimalPoint; bUnary = false; } } /** * Inputs a decimal point. */ public void dot() { if (!display.isError()) { if (!bDecimalPoint) { lDecimalFactor = 10; iDecPlaces = 0; } bDigits = bDigits; bDecimalPoint = true; bUnary = false; } } /** * Toggles the sign of the current number (R1 = -R1). */ public void sgn() { if (!display.isError()) { if (bDecimalPoint && iDecPlaces >= 1) { reg1ShowWithDecimals(-dReg1, iDecPlaces); } else { reg1Show(-dReg1); } } } /** * Clear all registers. */ public void c() { mc(); reg1Show(0d); ce(); iOpReg = NUL; } /** * Memory register (RM) clear. */ public void mc() { regMAssign(0d); } /** * Enter or result (=sign ). */ public void equ() { result(EQU); } /** * Percent operator. *

For more information see * the source code method result. */ public void prc() { result(PRC); } /** * Clear entry (R1 = 0). */ public void ce() { unary(CE); } /** * Memory read. */ public void mr() { unary(MR); } /** * Add to memory. */ public void madd() { unary(MADD); } /** * Substract from memory. */ public void msub() { unary(MSUB); } /** * Swap registers (R1 with R2). */ public void swap() { unary(SWAP); } /** * R1 = 1 / R1 */ public void inv() { unary(INV); } /** * R1 = 3.14156... */ public void pi() { unary(VPI); } /** * R1 = 2.71828... */ public void e() { unary(VE); } /** * R1 = ln(R1) */ public void ln() { unary(LN); } /** * R1 = log(R1) */ public void log() { unary(LOG); } /** * R1 = e^R1 */ public void exp() { unary(EXP); } /** * R1 = square_root(R1) */ public void sqrt() { unary(SQRT); } /** * R1 = R1 * R1 */ public void sqr() { unary(SQR); } /** * R1 = sin(R1) */ public void sin() { unary(SIN); } /** * R1 = arcsin(R1) */ public void asin() { unary(ASIN); } /** * R1 = cos(R1) */ public void cos() { unary(COS); } /** * R1 = arccos(R1) */ public void acos() { unary(ACOS); } /** * R1 = tan(R1) */ public void tan() { unary(TAN); } /** * R1 = arctan(R1) */ public void atan() { unary(ATAN); } /** * R1 = R1 + R2 */ public void add() { binary(ADD); } /** * R1 = R2 - R1 */ public void sub() { binary(SUB); } /** * R1 = R1 * R2 */ public void mul() { binary(MUL); } /** * R1 = R2 / R1 */ public void div() { binary(DIV); } /** * R1 = R2 ^ R1 */ public void pow() { binary(POW); } protected void unary(int iCurrentOp) { if (!display.isError()) { switch (iCurrentOp) { case CE: reg1Show(0d); break; case MR: reg1Show(dRegM); break; case VPI: reg1Show(Math.PI); break; case VE: reg1Show(Math.E); break; case SWAP: double dTemp; dTemp = dReg1; reg1Show(dReg2); dReg2 = dTemp; break; case SQRT: reg1Show(Math.sqrt(dReg1)); break; case INV: reg1Show(1d / dReg1); break; case LN: reg1Show(Math.log(dReg1)); break; case LOG: reg1Show(Math.log(dReg1) / Math.log(10)); break; case EXP: reg1Show(Math.exp(dReg1)); break; case SQR: reg1Show(dReg1 * dReg1); break; case SIN: reg1Show(Math.sin(toRad(dReg1))); break; case ASIN: reg1Show(toArc(Math.asin(toRad(dReg1)))); break; case COS: reg1Show(Math.cos(toRad(dReg1))); break; case ACOS: reg1Show(toArc(Math.acos(toRad(dReg1)))); break; case TAN: reg1Show(Math.tan(toRad(dReg1))); break; case ATAN: reg1Show(toArc(Math.atan(toRad(dReg1)))); break; case MADD: regMAssign(dRegM + dReg1); break; case MSUB: regMAssign(dRegM - dReg1); }; bDigits = false; bDecimalPoint = false; bUnary = true; } } protected void binary(int iNextOp){ if (!display.isError()) { if (bDigits || bUnary) { reg1Assign(dReg1); computeBinary(); dReg2 = dReg1; } iOpReg = iNextOp; bDigits = false; bDecimalPoint = false; bUnary = false; } } protected void result(int iNextOp){ if (!display.isError()) { if (!bDigits) opRegAssign(iOpReg); reg1Assign(dReg1); opRegAssign(iNextOp); switch (iNextOp) { case PRC: switch (iOpReg) { case MUL: reg1Show(dReg2 * dReg1 / 100); break; case DIV: reg1Show(dReg2 / (dReg1 / 100)); break; case ADD: reg1Show(dReg2 * (1 + dReg1 / 100)); break; case SUB: reg1Show(dReg2 * (1 - dReg1 / 100)); } break; case EQU: computeBinary(); break; } } if (!display.isError()) reg1Assign(dReg1); iOpReg = NUL; bDigits = false; bDecimalPoint = false; bUnary = false; } private void computeBinary() { switch (iOpReg) { case MUL: reg1Show(dReg1 * dReg2); break; case DIV: reg1Show(dReg2 / dReg1); break; case ADD: reg1Show(dReg1 + dReg2); break; case SUB: reg1Show(dReg2 - dReg1); break; case POW: reg1Show(Math.pow(dReg2, dReg1)); } } private double toRad(double dArg) { return dArg; } private double toArc(double dArg) { return dArg; } private protected void regMAssign(double dArg) { dRegM = display.showM(dArg); } private protected void reg1ShowWithDecimals(double dArg, int iDecimals) { dReg1 = display.showWithDecimals(dArg, iDecimals); } private protected void reg1AssignWithDecimals(double dArg, int iDecimals) { dReg1 = display.assignWithDecimals(dArg, iDecimals); } private protected void reg1Show(double dArg) { dReg1 = display.show(dArg); } private protected void reg1Assign(double dArg) { dReg1 = display.assign(dArg); } private protected void opRegAssign(int iOperator) { Integer oper = new Integer(iOperator); if (CalcHashtable.containsKey(oper)) display.showOp((String)CalcHashtable.get(oper)); } }