程序能实现基本的算术运算,并能够对运算结果的精度进行有效控制,并且实现了存储器相关功能
功能如下:
MC:清除存储数据 MR:读取存储数据显示在屏幕上 MS:将显示的数据覆盖存储到存储器中 M+:用存储的数据加上屏幕上显示的数并更新存储器里的值 M-: 用存储的数据减去屏幕上显示的数并更新存储器里的值 ←: 删除输入数的尾数 C: 清除计算器数据,下一次输入数据开始新的运算 CE: 清除当前输入的数 ±: 正负数转换 √: 开平方 +,-,*,/ 加减乘除,将结果 %:取模 1/x:取倒数
程序流程图:
代码实现:
class operateNum {//操作数类 public double value;//操作数的实际值 public int dotWei;//操作数如果是小数,记录小数点后的位数 public String invertedString;//1/x字符串 public String sqrtedString;//sqrt(x)字符串 public boolean isSqrted,isInverted;//做标记是否√,1/x过,用于后续判断 public boolean clear;//clear为真表示是否重置操作数 public boolean isFloat;//isFloat为真,表示操作数是小数 public operateNum() { value=0; dotWei=0; sqrtedString=null; invertedString=null; isSqrted=false; isInverted=false; clear=false; isFloat=false; } public void reset()//重置操作数 { value=0; dotWei=0; sqrtedString=null; invertedString=null; isSqrted=false; isInverted=false; clear=false; isFloat=false; } }
class storageField {//存储区 public double storageNum;//存储区存储的数据 public boolean storageMode;//是否启动存储区 public storageField() { storageNum=0; storageMode=false; } }
import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.math.BigDecimal; import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.LineBorder; public class calc extends JFrame{ private JTextField display1,display2,display3; private JButton num[],operate[]; private String name[]={"MC","MR","MS","M+","M-","←","CE","C","±","√","7","8","9","/","%","4","5","6","*","1/x","1","2","3","-","=","0",".","+"}; private operateNum op1=new operateNum(),op2=new operateNum();//操作数1,操作数2 private storageField storage=new storageField();//存储区 private String action="op1";//表示要操作的对象 "op1"操作第一个操作数,"op2"操作第二个操作数 private String sign="";//运算符,默认为空 private String screen1,screen2; private boolean Disable=false; public calc() { super("计算器"); this.setLayout(null); this.setSize(228, 324); this.setResizable(false); JPanel jp=new JPanel(null); jp.setBounds(10,15,getWidth()-24,getHeight()); jp.setBackground(new Color(217,228,241)); this.getContentPane().setBackground(new Color(217,228,241)); /**显示屏**/ display1=new JTextField(""); display2=new JTextField("0"); display3=new JTextField(""); display1.setEnabled(false); display2.setEnabled(false); display3.setEnabled(false); display1.setBounds(0, 0, 204, 26); display2.setBounds(20, 20, 184, 34); display3.setBounds(0, 20, 20, 34); display1.setHorizontalAlignment(JLabel.RIGHT); display2.setHorizontalAlignment(JLabel.RIGHT); display3.setHorizontalAlignment(JLabel.CENTER); display1.setFont(new Font("宋体",Font.PLAIN,12)); display2.setFont(new Font("宋体",Font.BOLD,20)); display3.setFont(new Font("宋体",Font.PLAIN,20)); display1.setDisabledTextColor(Color.BLACK); display2.setDisabledTextColor(Color.BLACK); display3.setDisabledTextColor(Color.BLACK); display1.setBorder(new LineBorder(new Color(242,247,252))); display2.setBorder(new LineBorder(new Color(242,247,252))); display3.setBorder(new LineBorder(new Color(242,247,252))); display1.setBackground(new Color(242,247,252)); display2.setBackground(new Color(242,247,252)); display3.setBackground(new Color(242,247,252)); /**按钮 35px*29px 28个***/ int i; operate=new JButton[28]; /**前24个**/ for(i=0;i<24;i++) { operate[i]=new JButton(name[i]); operate[i].setMargin(new java.awt.Insets(0,0,0,0)); operate[i].setBounds(i%5*(35+7), 60+i/5*(29+5)+5, 35, 29); jp.add(operate[i]); } /***=号***/ operate[i]=new JButton(name[i]); operate[i].setMargin(new java.awt.Insets(0,0,0,0)); operate[i].setBounds(i%5*(35+7), 60+i/5*(29+5)+5, 35, 29*2+5); jp.add(operate[i]); i++; /***0号***/ operate[i]=new JButton(name[i]); operate[i].setMargin(new java.awt.Insets(0,0,0,0)); operate[i].setBounds(i%5*(35+7), 60+i/5*(29+5)+5, 35*2+7, 29); jp.add(operate[i]); /**前24个**/ for(i=i+1;i<name.length;i++) { operate[i]=new JButton(name[i]); operate[i].setMargin(new java.awt.Insets(0,0,0,0)); operate[i].setBounds((i+1)%5*(35+7), 60+i/5*(29+5)+5, 35, 29); jp.add(operate[i]); } /** * 给按钮注册鼠标监听器,键盘监听器和背景 */ mouseAdapter ml=new mouseAdapter(); keyAdapter kl=new keyAdapter(); for(i=0;i<name.length;i++) { operate[i].addMouseListener(ml); operate[i].addKeyListener(kl); operate[i].setBackground(new Color(233,240,247)); operate[i].setForeground(new Color(30,57,91)); } jp.add(display1); jp.add(display2); jp.add(display3); jp.addKeyListener(kl); this.add(jp); this.setVisible(true); } class mouseAdapter extends MouseAdapter{ public void mouseClicked(MouseEvent e) { JButton operate=(JButton)e.getSource(); if(Disable)//禁用按钮,点击C 恢复计算器 { if(operate.getText()=="C") { clear(); Disable=false; } else return; } switch(operate.getText()) { case "MC":mc();break; case "MR":mr();break; case "MS":ms();break; case "M+":mAdd();break; case "M-":mCut();break; case "←":cutEnd();break; case "CE":cutNum();break; case "C":clear();break; case "±":revolt();break; case "√":sqrt();break; case "7": case "8": case "9": case "4": case "5": case "6": case "3": case "2": case "1": case "0":read(Integer.parseInt(operate.getText()));break;//将按键上的文本转化为Int型 case "/":divide();break; case "%":mo();break; case "*":mul();break; case "1/x":inverted();break; case "-":cut();break; case "+":add();break; case "=":sum();break; case ".":dot();break; } } public void mouseEntered(MouseEvent e) { ((JButton)e.getSource()).setBackground(new Color(255,211,113)); } public void mouseExited(MouseEvent e) { ((JButton)e.getSource()).setBackground(new Color(233,240,247)); } } /* * MC 取消存储区,清空存储区数据 */ public void mc() { storage.storageNum=0; storage.storageMode=false; display3.setText(null); } /* * MR 读取存储器存储的数据 */ public void mr() { op1.value=storage.storageNum; screen2=""+op1.value; if(op1.value==Math.floor(op1.value)) screen2=""+(int)op1.value; display2.setText(screen2); op1.clear=true; } /* * MS 保存数据到存储器 */ public void ms() { storage.storageNum=op1.value; display3.setText("M");//屏幕左下角显示M标志 } /* * M+ 已经储存的数加上当前计算结果并将和存入存储器 */ public void mAdd() { storage.storageNum=storage.storageNum+op1.value; } /* * M- 已经储存的数减去当前计算结果并将差存入存储器 */ public void mCut() { storage.storageNum=storage.storageNum-op1.value; } /* * ← 输入的数去掉尾数 * */ public void cutEnd() { if(action=="op1"&&op1.value!=0)//表示对op1进行操作 { if(op1.isFloat==false)//如果op1为整数 { op1.value=(int)op1.value/10; screen2=""+(int)op1.value; } else{//如果op1为小数 BigDecimal bd=new BigDecimal(op1.value); op1.value=bd.setScale(--op1.dotWei,BigDecimal.ROUND_DOWN).doubleValue(); screen2=""+op1.value; if(op1.dotWei==0)//小数点后数位都去除掉后,变位整数,更新isFloat标记 op1.isFloat=false; } } else if(action=="op2"&&op2.value!=0)//表示对op2进行操作 { if(op2.isFloat==false)//如果op2位整数 { op2.value=(int)op2.value/10; screen2=""+(int)op2.value; } else{//如果op2为小数 BigDecimal bd=new BigDecimal(op2.value); op2.value=bd.setScale(--op2.dotWei,BigDecimal.ROUND_DOWN ).doubleValue(); screen2=""+op2.value; if(op2.dotWei==0)//小数点后数位都去除掉后,变位整数,更新isFloat标记 op2.isFloat=false; } } display2.setText(screen2);//输出修改后的操作数 } /* * CE 清空当前操作数操作数 */ public void cutNum() { if(action=="op1") op1.reset(); else if(action=="op2") op2.reset(); display2.setText("0");//初始化显示屏2 } /* * C 归零 重置计算器 */ public void clear() { op1.reset(); op2.reset(); //初始化数据成员 action="op1"; sign=""; //初始化显示屏 display1.setText(""); display2.setText("0"); } /* * ± 正负号 */ public void revolt() { if(action=="op1") { op1.value=-op1.value; screen2=""+op1.value; } else if(action=="op2") { op2.value=-op2.value; screen2=""+op2.value; } display2.setText(screen2); } /* * √ 根号 */ public void sqrt() { double x;//临时变量 if(action=="op1") { op1.sqrtedString="sqrt("+op1.value+")"; op1.value=Math.sqrt(op1.value); op1.isSqrted=true; x=op1.value; } else { op2.sqrtedString="sqrt("+op2.value+")"; op2.value=Math.sqrt(op2.value); op2.isSqrted=true; x=op2.value; } screen2=x+""; if(x==Math.floor(x))//如果x为整数 { screen2=(int)x+"";//则将浮点数x先转化为int再转化成字符串 } display2.setText(screen2); } /* * 按下数字键 */ public void read(int value) { display2.setFont(new Font("宋体",Font.BOLD,20));//默认字体大小 display2.setText(null);//清屏 if(op1.clear==true) op1.reset(); if(op2.clear==true) op2.reset(); if(action=="op1")//表示输数据给op1 { if(op1.isFloat==true)//若op1为浮点数 { int i=1; double num=value; ++op1.dotWei; while(i<=op1.dotWei) { num*=0.1; i++; } op1.value=op1.value+num;//将新的小数点位添加到操作数op1中 //因为双精度浮点数 其精度比较高,而我们只需取它的op1.dotWei保存 op1.value=Double.parseDouble(String.format("%."+op1.dotWei+"f",op1.value)); //因为双精度浮点数 其精度比较高,而我们只需取它的op1.dotWei显示在屏幕上 display2.setText(String.format("%."+op1.dotWei+"f", op1.value)); } else//op1为整数 { op1.value=op1.value*10+value;//将新的整数位加倒op1中 display2.setText((int)op1.value+"");//屏幕输出op1的值 } } else if(action=="op2")//表示输数据给op2 { if(op2.isFloat==true)//若op2为浮点数 { int i=1; double num=value; ++op2.dotWei; while(i<=op2.dotWei) { num*=0.1; i++; } op2.value=op2.value+num;//将新的小数点位添加到操作数op2中 //因为双精度浮点数 其精度比较高,而我们只需取它的op2.dotWei保存 op2.value=Double.parseDouble(String.format("%."+op2.dotWei+"f",op2.value)); //因为双精度浮点数 其精度比较高,而我们只需取它的op2.dotWei显示在屏幕上 display2.setText(String.format("%."+op2.dotWei+"f", op2.value)); } else//op2为整数 { op2.value=op2.value*10+value; display2.setText((int)op2.value+""); } } } public void divide() { run("/"); } public void mo() { run("%"); } public void mul() { run("*"); } /* * 1/x */ public void inverted() { double num; String str; if(action=="op1") { op1.invertedString="1/"+op1.value;//1/x形式字符串 op1.value=1/op1.value; op1.isInverted=true; num=op1.value; } else{ op2.invertedString="1/"+op2.value;//1/x形式字符串 op2.value=1/op2.value; op1.isInverted=true; num=op2.value; } str=num+""; if(str.length()>=16)//计算器屏幕所能显示数据的最大长度 { display2.setFont(new Font("宋体",Font.BOLD,14));//缩小字体输出 display2.setText(str.substring(0, 16)); } else display2.setText(str); } public void cut() { run("-"); } public void add() { run("+"); } public void sum() { display2.setFont(new Font("宋体",Font.BOLD,20)); int d1=op1.dotWei,d2=op2.dotWei,i; switch(sign) { //运算后 结果保存到op1中 case "+":op1.value=op1.value+op2.value;break; case "-":op1.value=op1.value-op2.value;break; case "*":op1.value=op1.value*op2.value;break; case "/":op1.value=op1.value/op2.value;break; case "%":op1.value=op1.value%op2.value;break; } if(op2.value==0&&sign=="/")//除数为0 { Disable=true; display2.setText(op1.value+""); display1.setText(null); action="op1"; return ; } if(op1.value==Math.floor(op1.value))//结果为整数 { display2.setText((int)op1.value+""); op1.dotWei=0; op1.isFloat=false; } else{//结果为小数 String str=op1.value+""; //准确控制算术运算结果的精度,加,减,取模运算,小数点后的有效数字最多为max(d1,d2)位 if(sign.equals("+")||sign.equals("-")||sign.equals("%")) { i=d1>d2?d1:d2; str=op1.value+""; str=str.substring(0, str.indexOf(".")+i+1);//取i位输出 } //准确控制算术运算结果的精度,乘法运算,小数点后的有效数字最多为d1+d2位 else if(sign.equals("*")) { i=d1+d2; BigDecimal bd=new BigDecimal(op1.value); op1.value=bd.setScale(i,BigDecimal.ROUND_DOWN ).doubleValue(); str=op1.value+"";//更新修改后的str } //结果超过显示数据的最大长度 if(str.length()>=16) { display2.setFont(new Font("宋体",Font.BOLD,14)); str=str.substring(0, 16); } display2.setText(str); op1.dotWei=str.length()-str.indexOf(".")-1;//更新op1w值 } display1.setText(null); action="op1"; op1.clear=true;//开始新的表达式运算时,op1要先重置 op2.clear=true;//开始新的表达式运算时,op2要先重置 sign=""; } public void dot() { if(action=="op1") op1.isFloat=true; else op2.isFloat=true; display2.setText(display2.getText()+"."); } public void run(String SIGN) { display2.setFont(new Font("宋体",Font.BOLD,20)); action="op2"; int d1=op1.dotWei,d2=op2.dotWei,i; if(!sign.equals(""))//检测是否为以为表达式的第一运算 { switch(sign) {//运算后 结果保存到op1中 case "+":op1.value=op1.value+op2.value;break; case "-":op1.value=op1.value-op2.value;break; case "*":op1.value=op1.value*op2.value;break; case "/":op1.value=op1.value/op2.value;break; case "%":op1.value=op1.value%op2.value;break; } } String temp=isSpecileHandle(); if(temp==null) temp=display2.getText();//先保存display2文本框里的数据 if(op2.value==0&&sign=="/")//除数为0 { Disable=true; display2.setText(op1.value+""); display1.setText(display1.getText()+op1.value); } if(op1.value==Math.floor(op1.value))//结果为整数 { display2.setText((int)op1.value+""); op1.dotWei=0; op1.isFloat=false; } else{ String str=op1.value+""; //准确控制算术运算结果的精度,加,减,取模运算,小数点后的有效数字最多为max(d1,d2)位 if(sign.equals("+")||sign.equals("-")||sign.equals("%")) { i=d1>d2?d1:d2; BigDecimal bd=new BigDecimal(op1.value); op1.value=bd.setScale(i,BigDecimal.ROUND_DOWN ).doubleValue(); str=op1.value+"";//更新修改后的str } //准确控制算术运算结果的精度,乘法运算,小数点后的有效数字最多为d1+d2位 else if(sign.equals("*")) { i=d1+d2; BigDecimal bd=new BigDecimal(op1.value); op1.value=bd.setScale(i,BigDecimal.ROUND_DOWN ).doubleValue(); str=op1.value+"";//更新修改后的str } //结果超过显示数据的最大长度 if(str.length()>=16) { display2.setFont(new Font("宋体",Font.BOLD,14)); str=str.substring(0, 16); } display2.setText(str); op1.dotWei=str.length()-str.indexOf(".")-1;//每次加完后,如果结果op1的值为小数则更新op1w的值 } sign=SIGN; display1.setText(display1.getText()+temp+sign); op2.value=op1.value;//运算后,操作数op2默认的值为op1的值 op2.clear=true;//下一次键入数据,op2要重置 op1.clear=false;//下一次键入数据,op1不要重置 } /* * isSpecileHandle() * 操作数是否sqrt()或1/x过, * 如果有,则返回"sqrt(x)"或"1/x"字符串 */ public String isSpecileHandle() { String temp=null; if(op1.isSqrted) { temp=op1.sqrtedString; op1.isSqrted=false; } else if(op2.isSqrted) { temp=op2.sqrtedString; op2.isSqrted=false; } if(op1.isInverted) { temp=op1.invertedString; op1.isInverted=false; } else if(op2.isInverted) { temp=op2.invertedString; op2.isInverted=false; } return temp; } class keyAdapter extends KeyAdapter{ public void keyPressed(KeyEvent e) { int keycode=e.getKeyCode(); if((keycode>=96&&keycode<=105)||(keycode>=48&&keycode<=57))//数字键 { if(keycode>=96) keycode-=48; switch(keycode) { case 48:read(0);break; case 49:read(1);break; case 50:read(2);break; case 51:read(3);break; case 52:read(4);break; case 53:read(5);break; case 54:read(6);break; case 55:read(7);break; case 56:read(8);break; case 57:read(9);break; } } //运算符键+ - * / =和. 以及退格键(* =号) else if((keycode==110||keycode==46)||(keycode==111||keycode==47)||(keycode==45||keycode==109)||keycode==107||keycode==106||keycode==61||keycode==10||keycode==8) { if((keycode==110||keycode==46)) dot(); else if(keycode==111||keycode==47) run("/"); else if(keycode==45||keycode==109) run("-"); else if(keycode==107) run("+"); else if(keycode==106) run("*"); else if(keycode==61||keycode==10)//=号 sum(); else if(keycode==8) cutEnd(); } } } public static void main(String[] args) { // TODO Auto-generated method stub calc app=new calc(); } }
程序截图
时间: 2024-10-29 10:46:28