Skip to content
July 19, 2011 / oop123

Writing a Simple Calculator in Java – Part 3

Since the calculator can also add floating numbers, we will use BigDecimal to do all the calculations. Normal double does not have the precision required for exact calculations. It will made the code more complicated, but that is the price of accuracy. Some quick notes on BigDecimal: operations such as +, -, *, / are all replaced by .add(), .subtract(), .multiply(), .divide() on the BigDecimal object.

The following is just a code skeleton.

  • The enum defines the five ActionListeners for the +, -, *, /, and = buttons.
  • The .operate() method defines the Operation’s action
  • The .actionPerformed() will provide a skeleton call to .operate().
  • lastNum and lastOp are used to keep track of user input.
  • I did not add any precedence to the calculator (i.e. multiply before add), but if you want to know how to implement something like that see Stack Overflow and Wikipedia entry on it.
package gui.action;
import java.math.BigDecimal;
import java.awt.event.*;
import javax.swing.*;

public enum Operation implements ActionListener {
	ADD {
		@Override
		public String operate(BigDecimal num1, BigDecimal num2) {
			return null;
		}
	}, MINUS {
		@Override
		public String operate(BigDecimal num1, BigDecimal num2) {
			return null;
		}
	}, TIMES {
		@Override
		public String operate(BigDecimal num1, BigDecimal num2) {
			return null;
		}
	}, DIVIDE {
		@Override
		public String operate(BigDecimal num1, BigDecimal num2) {
			return null;
		}
	}, EQUAL {
		@Override
		public String operate(BigDecimal num1, BigDecimal num2) {
			return null;
		}
	};

	private static Operation lastOp = null;
	private static String lastNum = null;
	
	@Override
	public void actionPerformed(ActionEvent e) {}

	public abstract String operate(String BigDecimal num1, BigDecimal num2);
}

The code for .actionPerformed() is pretty self-explanatory. If the user entered a new number and there is a lastOp, calculate a result and display it. Set the lastOp to the new operation unless it’s an EQUAL, and set the lastNum to the current number. Finally, tell the calculator to start a new number.

if (lastOp != null && TypeNumber.hasNewNum()) {
	BigDecimal num1 = new BigDecimal(lastNum);
	BigDecimal num2 = new BigDecimal(CalcUtils.getNum())
	CalcUtils.setNum( CalcUtils.trimToMaxDigitsAndTrailing0IfNumIsFloat( lastOp.operate(num1, num2) ));
}
if (this != EQUAL) {
	lastOp = this;
}
lastNum = CalcUtils.getNum();
TypeNumber.startNewNum();

Now let’s write the individual operation.

ADD:

return num1.add(num2).toString();

MINUS:

return num1.subtract(num2).toString();

TIMES:

return num1.multiply(num2).toString();

DIVIDE:

return num1.divide(num2).toString();

EQUAL:

//NO NEED TO OVERRIDE -> .actionPerformed() do all the work already
return null;

The calculator can now do basic arithmetic! There are various bugs (or quirks) in it, like 1 / 6 * 6 gives 0.999999999999996 instead of 1, but oh well, it’s close enough 😛

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: