【Java】编程练习:简易计算器(BigDecimal 及其常用操作)

作业要求

编写Java GUI程序,实现一个简单计算器。要求如下:

(1)设计的界面如下图所示:窗体的标题栏显示“模拟计算器—江海大”,1个文本框用于显示输入字符和计算结果;20个按钮控件作为字符输入按键或者功能按键。
【Java】编程练习:简易计算器(BigDecimal 及其常用操作)_第1张图片
(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; }
        }
    }
}

简单测试

初始界面
【Java】编程练习:简易计算器(BigDecimal 及其常用操作)_第2张图片11111111111111112222222222222222+33333333333333335555555555555555

【Java】编程练习:简易计算器(BigDecimal 及其常用操作)_第3张图片
1.2 * 3.4 * 5.6 * 7.8
【Java】编程练习:简易计算器(BigDecimal 及其常用操作)_第4张图片
根号2(开平方的默认精度为64位)
【Java】编程练习:简易计算器(BigDecimal 及其常用操作)_第5张图片
2 ^ 2 ^ 2 ^ 2 ^ 2 ^ 2 ^ 2 ^ 2 ^ 2(^代表乘方)
输入2,按乘号9次。
【Java】编程练习:简易计算器(BigDecimal 及其常用操作)_第6张图片
114514666-123456-587
【Java】编程练习:简易计算器(BigDecimal 及其常用操作)_第7张图片
60/2/3/5/7(除不尽时默认截断成64位)
【Java】编程练习:简易计算器(BigDecimal 及其常用操作)_第8张图片

你可能感兴趣的:(基础课,#,Java)