Because there seems to be some bugs in the Blogger regarding pasting long code, the web page layout is broken. '<' characters inside the Java codes are sometimes misinterpreted as the left angle bracket of ab HTML element. You can download the whole Java project of the calculator from: https://sites.google.com/site/moderntone/JavaCalculator.zip?attredirects=0&d=1
Adder.java
import javax.swing.JTextField;
public class Adder {
private JTextField number1, number2;
public Adder(JTextField number1, JTextField number2){
this.number1 = number1; this.number2 = number2;
}
public String add(){
String n1 = number1.getText(), n2 = number2.getText();
if (n1.charAt(0) != '-' && n2.charAt(0) != '-') {}
else if (n1.charAt(0) == '-' && n2.charAt(0) == '-'){
number1.setText(number1.getText().substring(1));
number2.setText(number2.getText().substring(1));
return "-" + add();
}
else if (n1.charAt(0) != '-' && n2.charAt(0) == '-'){
number2.setText(number2.getText().substring(1));
Subtractor subtractor = new Subtractor(number1, number2);
return subtractor.subtract();
}
else{ //n1.charAt(0) == '-' && n2.charAt(0) != '-'
number1.setText(number1.getText().substring(1));
Subtractor subtractor = new Subtractor(number2, number1);
return subtractor.subtract();
}
AProcessor format = new AProcessor(n1, n2);
if (n1.contains(".") || n2.contains(".") ){
format.getProcessingInfo();format.getProcessingInfo2();
n1 = format.n1;n2 = format.n2;
String summation = addTwoPositiveIntegers(n1, n2);
summation = summation.substring(0, summation.length() - format.dotPosition + 1) + "." + summation.substring(summation.length() -
format.dotPosition + 1);
summation = Utils.adjustAnswer(summation);
return Utils.trimEndZeros(summation);
}
else {
format.getProcessingInfo2();
n1 = format.n1;n2 = format.n2;
return Utils.trimZeros(addTwoPositiveIntegers(n1, n2));
}
}
private String addTwoPositiveIntegers(String n1, String n2){
int[] n1digits = Utils.convertStringToDigits(n1), n2digits = Utils.convertStringToDigits(n2);
return getAdditionResult(n1digits, n2digits);
}
private String getAdditionResult(int[] n1digits, int[] n2digits){
int [] answerDigits = new int[n1digits.length];
for (int i = answerDigits.length -1 ; i >= 1; i--){
answerDigits[i] += n1digits[i] + n2digits[i];
if (answerDigits[i] >= 10){
answerDigits[i] -= 10;answerDigits[i-1]++;
}
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < answerDigits.length; i++)
builder.append(answerDigits[i]);
return Utils.trimZeros(builder.toString());
}
}
AProcessor.java public class AProcessor {
public String n1, n2;
public int dotPosition;
public AProcessor(String n1, String n2){
this.n1 = n1;
this.n2 = n2;
}
public void getProcessingInfo(){
//counted from the right: 0, 1, 2, .., dotPosition
if (!n1.contains(".")) n1 +=".0";
if (!n2.contains(".")) n2 +=".0";
int i1 = n1.indexOf("."), i2 = n2.indexOf(".");
String n1afterdot = n1.substring(i1), n2afterdot = n2.substring(i2);
//when n1 is 3.34 and n2 is 23.3453, convert n1 to 3.3400
int numberOfAdditionalZerosRightSideOfDot = n1afterdot.length() > n2afterdot.length() ?
n1afterdot.length() - n2afterdot.length() : n2afterdot.length() - n1afterdot.length();
if (n1.substring(i1).length() > n2.substring(i2).length()){
dotPosition = n1.length() - i1;
for (int i = 0 ; i < numberOfAdditionalZerosRightSideOfDot ; i++) n2 += "0";
}
else {
dotPosition = n2.length() - i2;
for (int i = 0 ; i < numberOfAdditionalZerosRightSideOfDot ; i++) n1 += "0";
}
n1 = n1.replace(".", "");n2 = n2.replace(".", "");
}
public void getProcessingInfo2(){
int numberOfAdditionalZeros = n1.length() > n2.length() ?
n1.length() - n2.length() + 1: n2.length() - n1.length() + 1;
if (n1.length() > n2.length()){
n1 = "0" + n1; n2 = getConsecutiveZeros(numberOfAdditionalZeros) + n2;
}
else {
n2 = "0" + n2; n1 = getConsecutiveZeros(numberOfAdditionalZeros) + n1;
}
}
private static String getConsecutiveZeros(int n){
StringBuilder builder = new StringBuilder();
while (n > 0) {
builder.append("0");n--;
}
return builder.toString();
}
}
Calculator.java import java.awt.EventQueue;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.regex.*;
public class Calculator extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField number1, number2, answer;
private String number1_bak, number2_bak;
private JComboBox operation;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Calculator frame = new Calculator();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Calculator() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(450, 100, 500, 240);
setTitle("Java Calculator");
setResizable(false);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
setContentPane(contentPane);
JLabel lblNewLabel = new JLabel("A calculator that supports basic math operations");
lblNewLabel.setForeground(Color.BLUE);
lblNewLabel.setFont(new Font("Dialog", Font.PLAIN, 16));
lblNewLabel.setBounds(75, 23, 340, 21);
contentPane.add(lblNewLabel);
number1 = new JTextField();
number1.setBackground(Color.YELLOW);
number1.setBounds(130, 64, 253, 21);
number1.setToolTipText("Input a number");
number1.addKeyListener(enterListener);
contentPane.add(number1);
number2 = new JTextField();
number2.setBackground(Color.YELLOW);
number2.setBounds(130, 98, 253, 21);
number2.addKeyListener(enterListener);
number2.setToolTipText("Input a number");
contentPane.add(number2);
operation = new JComboBox();
operation.setFont(new Font("Segoe UI Light", Font.PLAIN, 24));
operation.setModel(new DefaultComboBoxModel(new String[] {"+", "-", "×", "÷"}));
operation.setBounds(75, 95, 45, 28);
operation.addKeyListener(enterListener);
contentPane.add(operation);
JSeparator separator = new JSeparator();
separator.setBounds(60, 138, 380, 2);
contentPane.add(separator);
answer = new JTextField();
answer.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.GRAY, null));
answer.setEditable(false);
answer.setBackground(Color.CYAN);
answer.setColumns(10);
answer.setBounds(130, 150, 253, 21);
contentPane.add(answer);
JButton btnNewButton = new JButton("Enter");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
performAction();
}
});
btnNewButton.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
btnNewButton.setBounds(395, 97, 64, 23);
contentPane.add(btnNewButton);
}
private void performAction(){
number1_bak = number1.getText();number2_bak = number2.getText();
if (checkInputError(number1) || checkInputError(number2)){
number1.setText(number1_bak); number2.setText(number2_bak);
JOptionPane.showMessageDialog(null, "Please input valid double numbers for calculation.");
return;
}
switch (operation.getSelectedItem().toString().charAt(0)) {
case '+':
Adder adder = new Adder(number1, number2);
answer.setText(adder.add());
break;
case '-':
Subtractor subtractor = new Subtractor(number1, number2);
answer.setText(subtractor.subtract());
break;
case '×':
Multiplicator multiplicator = new Multiplicator(number1, number2);
answer.setText(multiplicator.multiply());
break;
case '÷':
Divisor divisor = new Divisor(number1, number2);
answer.setText(divisor.divide());
break;
default:
break;
}
number1.setText(number1_bak); number2.setText(number2_bak);
}
private KeyListener enterListener = new KeyListener() {
@Override
public void keyTyped(KeyEvent arg0) {}
@Override
public void keyReleased(KeyEvent arg0) {}
@Override
public void keyPressed(KeyEvent arg0) {
if (arg0.getKeyCode() == KeyEvent.VK_ENTER){
performAction();
}
}
};
private boolean checkInputError(JTextField inputValue){
if (inputValue.getText().length() == 0)
return true;
if (inputValue.getText().charAt(0) == '+')
inputValue.setText(inputValue.getText().substring(1));
Pattern pattern = Pattern.compile("^-?\\d*\\.?\\d+$");
Matcher matcher = pattern.matcher(inputValue.getText());
if (!matcher.find()){
return true;
}
return false;
}
}
Divisor.java import java.util.ArrayList;
import java.util.List;
import javax.swing.JTextField;
public class Divisor {
private static final int limitForAnswer = 30;
private JTextField number1, number2;
private List tempDigits = new ArrayList();
public Divisor(JTextField number1, JTextField number2){
this.number1 = number1; this.number2 = number2;
}
public String divide(){
String n1 = number1.getText(), n2 = number2.getText();
if (n1.charAt(0) != '-' && n2.charAt(0) != '-') {}
else if (n1.charAt(0) == '-' && n2.charAt(0) == '-'){
number1.setText(number1.getText().substring(1));
number2.setText(number2.getText().substring(1));
return divide();
}
else if (n1.charAt(0) != '-' && n2.charAt(0) == '-'){
number2.setText(number2.getText().substring(1));
String answer = divide();
return answer.contains("Not") ? "Not a number" : "-" + answer;
}
else{ //n1.charAt(0) == '-' && n2.charAt(0) != '-'
number1.setText(number1.getText().substring(1));
String answer = divide();
return answer.contains("Not") ? "Not a number" : "-" + answer;
}
if (n1.contains(".") || n2.contains(".") ){
n1 = someProcess(n1); n2 = someProcess(n2);
if (n2.equals("0"))
return "Not a number";
else if (n1.equals("0"))
return "0";
String tempDividend = Utils.trimZeros(n1.replace(".", ""));
String divisor = Utils.trimZeros(n2).replace(".", "");
divisor = Utils.trimEndZeros(divisor); tempDividend = Utils.trimEndZeros(tempDividend);
divideTwoNums(tempDividend, divisor);
if (!n1.contains(".")) n1 = n1 +".0";
if (!n2.contains(".")) n2 = n2 +".0";
String answer = shiftAndGetAnswer(n1, n2);
return answer;
}
else {
if (Utils.trimZeros(n2).equals("0"))
return "Not a number";
else {
number1.setText(n1 +".0");number2.setText(n2 +".0");
return divide();
}
}
}
private String shiftAndGetAnswer(String n1, String n2){
int log10n1 = getLog10n(n1), log10n2 = getLog10n(n2);
StringBuilder builder;
int log10Value = log10n1 - log10n2;
if (log10Value +1 > tempDigits.size()){
builder = new StringBuilder("");
for (int i = 0; i < tempDigits.size() ; i++)
builder.append(tempDigits.get(i));
int temp = log10Value + 1 - tempDigits.size();
for (int i = 0; i < temp ; i++){
builder.append("0");
}
return Utils.trimZeros(builder.toString());
}
else if (log10Value > 0){
builder = new StringBuilder("");
for (int i = 0 ; i < log10Value+1; i++)
builder.append(tempDigits.get(i));
builder.append('.');
int temp = tempDigits.size() - log10Value -1;
if (temp > 0){
for (int i = 0 ; i < temp; i++)
builder.append(tempDigits.get(i + log10Value));
}
else {
builder.append('0');
}
return Utils.trimZeros(builder.toString());
}
else {
builder = new StringBuilder("");
for (int i = 0 ; i < tempDigits.size() ; i++)
builder.append(tempDigits.get(i));
return builder.insert(1, '.').toString();
}
}
private String someProcess(String number){
number = Utils.trimZeros(number);
number = Utils.adjustAnswer(number);
number = Utils.trimEndZeros(number);
return number;
}
private static int getLog10n(String number){
if (number.charAt(0) == '0'){
int i;
for (i = 2; i < number.length(); i++){
if (number.charAt(i) != '0')
break;
}
return 1-i;
}
else {
return number.indexOf('.') -1;
}
}
private int getDigit(String string, int index){
return string.charAt(index) -'0';
}
/**
* For example, if n1 = 14 and n2 = 3, the result is 4666666... (stored in tempDigits)
* @param n1, n2
* @return
*/
private void divideTwoNums(String tempDividend, String divisor){
int upperBound, lowerBound;
String product, target;
upperBound = (getDigit(tempDividend, 0) + 1) / getDigit(divisor, 0);
lowerBound = getDigit(tempDividend, 0) / (getDigit(divisor, 0) + 1);
if (tempDividend.length() < divisor.length())
tempDividend = dweiChi(tempDividend, divisor.length() - tempDividend.length());
target = tempDividend.substring(0, divisor.length());
List succeedingDigits = new ArrayList();
if (tempDividend.length() > divisor.length()){
String succeedingString = tempDividend.substring(divisor.length());
for (int i = 0 ; i < succeedingString.length(); i ++)
succeedingDigits.add(succeedingString.charAt(i));
}
int i;
for (i = lowerBound; i <= upperBound; i++){
Multiplicator multiplicator = new Multiplicator("" + i, divisor);
product = multiplicator.multiply();
if (product.length() > target.length()) target = "0" + target;
if (product.compareTo(target) > 0)
break;
}
tempDigits.add(i-1);
Multiplicator multiplicator = new Multiplicator("" + (i-1), divisor);
product = multiplicator.multiply();
Subtractor subtractor = new Subtractor(tempDividend.substring(0, divisor.length()), product);
target = subtractor.subtract();
int targetStandardLength = divisor.length() + 1;
int count = 0;
while (count < limitForAnswer){
if (succeedingDigits.size() == 0)
target = target + "0";
else {
target = target + succeedingDigits.get(0);
succeedingDigits.remove(0);
}
if (target.length() < targetStandardLength)
target = dweiChi(target, targetStandardLength - target.length());
lowerBound = (getDigit(target, 0) * 10 + getDigit(target, 1) ) / (getDigit(divisor, 0) + 1);
upperBound = (getDigit(target, 0) * 10 + getDigit(target, 1) + 1) / getDigit(divisor, 0);
for (i = lowerBound; i <= upperBound + 1; i++){
multiplicator = new Multiplicator("" + i, divisor);
product = multiplicator.multiply();
if (product.length() < target.length()) product = dweiChi(product, target.length() - product.length());
else if (product.length() > target.length()) target = dweiChi(target, product.length() - target.length());
if (product.compareTo(target) > 0)
break;
}
tempDigits.add(i-1);
multiplicator = new Multiplicator("" + (i-1), divisor);
product = multiplicator.multiply();
subtractor = new Subtractor(target, product);
target = subtractor.subtract();
if (isZero(target) && succeedingDigits.size() == 0)
break;
count ++;
}
}
private String dweiChi(String string, int zeroNum){
StringBuilder builder = new StringBuilder(string);
for (int i = 0 ; i < zeroNum;i ++)
builder.insert(0, '0');
return builder.toString();
}
private boolean isZero(String target){
for (int i = 0 ; i < target.length(); i++){
if (target.charAt(i) != '0')
return false;
}
return true;
}
}
Multiplicator.java import javax.swing.JTextField;
public class Multiplicator {
private JTextField number1, number2;
public Multiplicator(JTextField number1, JTextField number2){
this.number1 = number1; this.number2 = number2;
}
public Multiplicator(String number1, String number2){
this.number1 = new JTextField(number1);this.number2 = new JTextField(number2);
}
public String multiply(){
String n1 = number1.getText(), n2 = number2.getText();
if (n1.charAt(0) != '-' && n2.charAt(0) != '-') {}
else if (n1.charAt(0) == '-' && n2.charAt(0) == '-'){
number1.setText(number1.getText().substring(1));
number2.setText(number2.getText().substring(1));
return multiply();
}
else if (n1.charAt(0) != '-' && n2.charAt(0) == '-'){
number2.setText(number2.getText().substring(1));
return "-" + multiply();
}
else{ //n1.charAt(0) == '-' && n2.charAt(0) != '-'
number1.setText(number1.getText().substring(1));
return "-" + multiply();
}
if (n1.contains(".") || n2.contains(".") ){
n1 = preprocess(n1); n2 = preprocess(n2);
String tempn1 = n1.replace(".", ""), tempn2 = n2.replace(".", "");
String tempMultiplication = multiplyTwoPositiveIntegers(tempn1, tempn2);
int shiftHowManyTimes = (n1.length() - n1.indexOf('.') -1) + (n2.length() - n2.indexOf('.') -1);
StringBuilder builder = new StringBuilder(tempMultiplication + ".0");
for (int i = 0 ; i < shiftHowManyTimes; i ++)
builder = Utils.shiftRight(builder);
return Utils.trimEndZeros(builder.toString()) ;
}
else
return multiplyTwoPositiveIntegers(n1, n2);
}
private String preprocess(String n){
if (!n.contains(".")) n += ".0";
if (n.charAt(0) == '.') n= "0" + n;
return n;
}
private String multiplyTwoPositiveIntegers(String n1, String n2){
int[] n1digits = Utils.convertStringToDigits(n1), n2digits = Utils.convertStringToDigits(n2);
n1digits = reverse(n1digits);n2digits = reverse(n2digits);
int[] answerDigits = new int[n1digits.length + n2digits.length];
for (int i = 0 ; i < n1digits.length; i++){
for (int j = 0 ; j < n2digits.length; j++){
int temp = n1digits[i]*n2digits[j];
answerDigits[i+j] += temp;
}
}
for (int i = 0 ; i < answerDigits.length -1; i ++){
answerDigits[i+1] += answerDigits[i] / 10;
answerDigits[i] = answerDigits[i] % 10;
}
StringBuilder builder = new StringBuilder();
for (int i = answerDigits.length - 1 ; i >= 0; i--)
builder.append(answerDigits[i]);
return Utils.trimZeros(builder.toString());
}
private int[] reverse(int[] digits){
int[] result = new int[digits.length];
for (int i = 0 ; i
Subtractor.java
import javax.swing.JTextField;
public class Subtractor {
private JTextField number1, number2;
public Subtractor(JTextField number1, JTextField number2){
this.number1 = number1; this.number2 = number2;
}
public Subtractor(String number1, String number2){
this.number1 = new JTextField(number1);this.number2 = new JTextField(number2);
}
public String subtract(){
String n1 = number1.getText(), n2 = number2.getText();
if (n1.charAt(0) != '-' && n2.charAt(0) != '-') {}
else if (n1.charAt(0) == '-' && n2.charAt(0) == '-'){
number1.setText(number1.getText().substring(1));
number2.setText(number2.getText().substring(1));
Subtractor subtractor = new Subtractor(number2, number1);
return subtractor.subtract();
}
else if (n1.charAt(0) != '-' && n2.charAt(0) == '-'){
number2.setText(number2.getText().substring(1));
Adder adder = new Adder(number1, number2);
return adder.add();
}
else{ //n1.charAt(0) == '-' && n2.charAt(0) != '-'
number1.setText(number1.getText().substring(1));
Adder adder = new Adder(number1, number2);
return "-" + adder.add();
}
AProcessor format = new AProcessor(n1, n2);
if (n1.contains(".") || n2.contains(".") ){
format.getProcessingInfo();format.getProcessingInfo2();
n1 = format.n1;n2 = format.n2;
String subtraction = subtractTwoPositiveIntegers(n1, n2);
subtraction = subtraction.substring(0, subtraction.length() - format.dotPosition + 1) + "." + subtraction.substring
(subtraction.length() - format.dotPosition + 1);
subtraction = Utils.adjustAnswer(subtraction);
return Utils.trimEndZeros(subtraction);
}
else {
format.getProcessingInfo2();
n1 = format.n1;n2 = format.n2;
return subtractTwoPositiveIntegers(n1, n2);
}
}
public String subtract_buLin(int length){
String tempResult = subtract();
int zerosNum = length - tempResult.length();
StringBuilder builder = new StringBuilder(tempResult);
for (int i = 0 ; i < zerosNum; i ++)
builder.insert(0, '0');
return builder.toString();
}
private String subtractTwoPositiveIntegers(String n1, String n2){
if (n1.compareTo(n2) >= 0){
int[] n1digits = Utils.convertStringToDigits(n1), n2digits = Utils.convertStringToDigits(n2);
return getSubtractionResult(n1digits, n2digits);
}
else {
return "-" + subtractTwoPositiveIntegers(n2, n1);
}
}
private String getSubtractionResult(int[] n1digits, int[] n2digits ){
int [] answerDigits = new int[n1digits.length];
for (int i = 0; i < answerDigits.length ; i++){
answerDigits[i] += n1digits[i] - n2digits[i];
}
for (int i = answerDigits.length - 1; i >= 0; i--){
if (answerDigits[i] < 0){
answerDigits[i] += 10;
answerDigits[i-1]--;
}
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < answerDigits.length; i++)
builder.append(answerDigits[i]);
return Utils.trimZeros(builder.toString());
}
}
Utils.java
public class Utils {
/**
* @param args
*/
public static void main(String[] args) {
String test = "003400";String wew;
wew= Utils.trimZeros(Utils.trimEndZeros(test)).replace(".", "");
System.out.println(wew);
}
public static String trimZeros(String answer){
int i;
for (i = 0 ; i < answer.length(); i++){
if (answer.charAt(i) != '0')
break;
}
if (i != answer.length())
return answer.substring(i);
else
return "0";
}
public static String trimEndZeros(String number){ //trim end zeros for decimal numberss
StringBuilder builder = new StringBuilder(number);
if (number.contains(".")){
int index = number.length() - 1;
while (builder.charAt(index) == '0') {
builder.deleteCharAt(index);
index --;
}
if (builder.charAt(index) == '.')
builder.deleteCharAt(index);
}
return builder.toString();
}
public static String adjustAnswer(String answer){
if (answer.charAt(0) =='.')
answer = "0" + answer;
else if (answer.charAt(0) == '-' && answer.charAt(1) == '.'){
answer = "-0" + answer.substring(1);
}
return answer;
}
public static StringBuilder shiftRight(StringBuilder number){
if (number.toString().contains(".")){
if (number.charAt(0) == '0'){
number.insert(2, '0');
}
else if (number.charAt(1) == '.'){//6.7 -> 0.67
number.deleteCharAt(1);
number.insert(0, '.');number.insert(0, '0');
}
else {//457.3 -> 45.73
int dotIndex = number.indexOf(".");
number.deleteCharAt(dotIndex);
number.insert(dotIndex -1, '.');
}
}
else {
System.out.println("there is bug ");System.exit(0);
return null;
}
return number;
}
public static int[] convertStringToDigits(String string){
int[] result = new int[string.length()];
for (int i = 0 ; i < string.length(); i++)
result[i] = string.charAt(i) - '0';
return result;
}
public static int[] convertStringToDigits(String string, int length){
int howMany = length - string.length();int count = 0;
StringBuilder newString = new StringBuilder(string);
do {
newString.append('0');
} while(++count < howMany);
return convertStringToDigits(newString.toString());
}
}
No comments:
Post a Comment