【Java】編程練習:簡易計算器(BigDecimal 及其常用操作)

作業要求

編寫Java GUI程序,實現一個簡單計算器。要求如下:

(1)設計的界面如下圖所示:窗體的標題欄顯示“模擬計算器—江海大”,1個文本框用於顯示輸入字符和計算結果;20個按鈕控件作爲字符輸入按鍵或者功能按鍵。
在這裏插入圖片描述
(2)計算功能:實現加、減、乘、除等雙目運算,開平方、百分數等單目運算;

(3)輔助功能:按鈕“C”清空文本框;按鈕“←”退格,刪除文本框中最右邊的一個字符。

代碼

爲了鍛鍊大家閱讀代碼的能力,本篇博文不包含代碼的詳細註釋,只說明幾點:
1、Java 不像 C / C++ 那樣具有手動釋放內存的函數。Java 由垃圾收集器(Garbage Collecter)來清除不再被變量引用的內存對象。
2、BigDecimal 對象一旦建立,不能修改。如果要修改某個 BigDecimal 變量的值,只能再次進行 new 操作。這個變量會指向內存中新建的新的 BigDecimal 的值,原有的 BigDecimal 成爲內存碎片,往後將被垃圾收集器自動回收(GC 一般不會立即回收不再被引用的對象)。
3、通過 BigDecimal 進行除法時,如果除不盡,會產生異常。本程序處理這個異常的方法是設定保留的小數位數(默認爲 64 位)並重新計算。
4、BigDecimal 類的成員變量中的指定四捨五入方式的常量已經棄用,指定四捨五入方式請通過 java.math.RoundingMode 中的常量指定。
5、由於時間關係,我沒有增加處理鍵盤響應的代碼,因此這個簡易計算器無法通過鍵盤輸入。這部分就暫時先鴿了,等我十分空閒時會考慮補充。
6、代碼橫向長度較長,建議複製到 IDE 中,將 IDE 的窗口最大化後再進行查看。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.math.MathContext;
import java.math.RoundingMode;
import java.math.BigDecimal;
import java.math.BigInteger;
public class Calc {
    public static void main(String[] args) { Main m = new Main(); }
}
class Global {
    public static JTextField text = new JTextField("0");
    public static final int scale = 64;
}
class Main {
    JFrame frame = new JFrame("模擬計算器——江海大");
    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    JPanel panel = new JPanel(new GridLayout(5, 4));
    Inputter inputter = new Inputter();
    String name[] = { "C", "÷", "×", "←","7", "8", "9", "-", "4", "5", "6", "+", "1", "2", "3", "√", "%", "0", ".", "=" };
    JButton button[] = new JButton[name.length];
    Main() {
        Global.text.setEditable(false);
        frame.setLayout(new BorderLayout()); frame.setBounds(screen.width / 2 - 320, screen.height / 2 - 180, 640, 360);
        frame.setResizable(false); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel, BorderLayout.CENTER); frame.add(Global.text, BorderLayout.NORTH);
        for (int i = 0; i < button.length; ++i) {
            button[i] = new JButton(name[i]); panel.add(button[i]); button[i].addActionListener(inputter);
        }
        frame.setVisible(true);
    }
}
class Inputter implements ActionListener {
    String t = new String(); int operator = 0;
    boolean isRhs = false, decimalPoint = false, nextInput = false;
    final String defaultString = new String("0");
    final BigDecimal p = new BigDecimal(100); final MathContext m = new MathContext(Global.scale);
    final BigInteger zero = new BigInteger("0");
    BigDecimal x = new BigDecimal(0), y = new BigDecimal(0), z = new BigDecimal(zero, 0);
    void compute() {
        switch (operator) {
        default:x = x.add(y); break;
        case 1:x = x.subtract(y); break;
        case 2:x = x.multiply(y); break;
        case 3:
            try { x = x.divide(y); }
            catch (java.lang.ArithmeticException e) { x = x.divide(y, Global.scale, RoundingMode.HALF_UP); }
        }
        Global.text.setText(x.toString()); nextInput = true;
        z = x; if (z == x) { decimalPoint = false; }
    }
    public void actionPerformed(ActionEvent e) {
        String s = e.getActionCommand();
        if (s.charAt(0) >= '0' && s.charAt(0) <= '9') {
            if (nextInput) { Global.text.setText(s); nextInput = false; }
            else {
                t = Global.text.getText();
                if (!t.equals(defaultString)) { Global.text.setText(t + s.charAt(0)); }
                else { Global.text.setText(s); }
            }
        }
        else if (s.charAt(0) == '.') {
            if (decimalPoint == false) { Global.text.setText(Global.text.getText() + s.charAt(0)); decimalPoint = true; }
        }
        else if (s.charAt(0) == '%') {
            if (isRhs == false) { x = new BigDecimal(Global.text.getText()); x = x.multiply(p); Global.text.setText(x.toString()); }
            else { y = new BigDecimal(Global.text.getText()); y = y.multiply(p); Global.text.setText(y.toString()); }
        }
        else if (s.charAt(0) == '√') {
            if (isRhs == false) { x = new BigDecimal(Global.text.getText()); x = x.sqrt(m); Global.text.setText(x.toString()); }
            else { y = new BigDecimal(Global.text.getText()); y = y.sqrt(m); Global.text.setText(y.toString()); }
        }
        else if (s.charAt(0) == '+') {
            if (isRhs == false) { x = new BigDecimal(Global.text.getText()); operator = 0; nextInput = true; isRhs = true; }
            else { y = new BigDecimal(Global.text.getText()); compute(); isRhs = true; }
            decimalPoint = false; 
        }
        else if (s.charAt(0) == '-') {
            if (isRhs == false) { x = new BigDecimal(Global.text.getText()); operator = 1; nextInput = true; isRhs = true; }
            else { y = new BigDecimal(Global.text.getText()); compute(); }
            decimalPoint = false; 
        }
        else if (s.charAt(0) == '×') {
            if (isRhs == false) { x = new BigDecimal(Global.text.getText()); operator = 2; nextInput = true; isRhs = true; }
            else { y = new BigDecimal(Global.text.getText()); compute(); }
            decimalPoint = false; 
        }
        else if (s.charAt(0) == '÷') {
            if (isRhs == false) { x = new BigDecimal(Global.text.getText()); operator = 3; nextInput = true; isRhs = true; }
            else { y = new BigDecimal(Global.text.getText()); compute(); }
            decimalPoint = false; 
        }
        else if (s.charAt(0) == '←') {
            t = Global.text.getText(); if (t.charAt(t.length() - 1) == '.') { decimalPoint = false; }
            if (t.length() > 1)Global.text.setText(t.substring(0, t.length() - 1));
            else Global.text.setText(defaultString);
        }
        else if (s.charAt(0) == 'C') {
            isRhs = decimalPoint = false; Global.text.setText(defaultString);
            x = BigDecimal.valueOf(0); y = BigDecimal.valueOf(0);
        }
        else if (s.charAt(0) == '=') {
            if (isRhs) { y = new BigDecimal(Global.text.getText()); compute(); isRhs = false; }
        }
    }
}

簡單測試

初始界面
在這裏插入圖片描述11111111111111112222222222222222+33333333333333335555555555555555

在這裏插入圖片描述
1.2 * 3.4 * 5.6 * 7.8
在這裏插入圖片描述
根號2(開平方的默認精度爲64位)
在這裏插入圖片描述
2 ^ 2 ^ 2 ^ 2 ^ 2 ^ 2 ^ 2 ^ 2 ^ 2(^代表乘方)
輸入2,按乘號9次。
在這裏插入圖片描述
114514666-123456-587
在這裏插入圖片描述
60/2/3/5/7(除不盡時默認截斷成64位)
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章