8.4 如何用JS写计算器

来源:互联网 发布:cnc数控机床编程 编辑:程序博客网 时间:2024/06/07 01:06

用JS写计算器可以有很多种方法,最近我刚刚用JS编写一个计算器,

下面我来谈谈我自己的方法:

首先,让我们从计算器的基本运算来考虑,比如

    1            +            2        =       3

数字A   运算符号   数字B  等号  结果

这里的数字我使用了两个字符串str1、str2来表示,虽然它们本身可能是整型或者浮点类型,但是用字符串来表示,可以与各种符号使用统一的表示类型,为后续的操作带来不少方便。

上述例子是一个基本的整数运算过程,这个过程在计算器操作上可以分解成以下几步

1、用户输入数字A

调用函数 input(value),value的值为对应的数字或小数点,

function input (a) {

if (end&&(!op)) {Clear();  //检查结束标志,是否继续运算
str1=str1+a;
display (a);
}

字符串str1用来表示当前输入的数字,数字的每一位即是一个字符,把这个字符用a来表示,可以用str1=str1+a;语句来得到最终输入的数字。


2、用户输入运算符号

调用函数 operation(b),参数1、2、3、4分别对应+-*/四种运算符号,

function operation (b) {
if (!op) {               //检查运算符号是否重复输入
op=b;
str2=str1;
str1="";
  switch (op){
  case 1:display("+");         //加法标志
    break;
    case 2:display("-")         //减法标志
    break;
    case 3:display("*")//乘法标志
    break;
    case 4:display("/")//除法标志
    break;}
};
}

op=b,op作为运算符号标志,记录用户输入的运算操作。当用户开始输入运算符时,说明数字A已输入完毕,str2=str1; 把str1的值,即数字A保存在str2中,str1=""; str1清空,准备存入下一个输入数字B。


3、用户输入数字B

这一步与第一步输入数字A相同。


4、用户输入等号

调用函数 equal(),

function equal () {
switch (op){
case 1:num1=accAdd(str2, str1);
break;
case 2:num1=accSub(str2, str1);
break;
case 3:num1=accMul(str2, str1);
break;
case 4:num1=accDiv(str2, str1);
break;
}
Clear();
str1=num1.toString();
display(str1);
end = true;       //运算结束标志
}

switch语句根据op的不同值执行相应的运算,num1来储存运算结果,接着执行函数Clear();

function Clear () {
str1 = "";
str2 = "";
op = 0;
end = false;
document.getElementById("disText").value="0";
}

str1、str2、op清空,屏幕显示归零,一切状态复原。然后,num1转化为字符串形式赋予str1,display(str1);显示计算结果,end = true;  表示一次运算结束。


这四步结束后,如果用户还要继续计算,则函数 input()中的判断语句if (end&&(!op)) {Clear();将会发生作用。

1.如果用户想利用运算结果进行计算,那么他肯定要先输入一个运算符号,此时op将被赋予一个非零的值,str1中的运算结果转存在str1中,此时运算结果相当于数字A,当用户紧接着输入另一个数字的时候,end=true,!op=0,if语句内的Clear()不执行,数字正常存在str1中,之后按部就班的完成整个计算;

2.如果用户想进行一次全新的计算,那么他将会直接输入新的数字,end=true,op=0,在input()中的if语句执行Clear(),将会清空str1,删除运算结果,用来存放新输入的数字,使运算正常进行。


看过了整数计算,如果加入小数和负数又该怎么办呢?

小数计算

浮点数其实跟整数相比无非就是多了一个小数点嘛,因为数字都是用字符串表示的,小数点"."也是一个字符,所以其实和一位数字没有区别,完全可以用相同的方式对待,当用户输入小数点时只需调用input(".")就可以了。


负数运算

num1=parseFloat(str1);
num2=-num1;
str1=num2.toString();

取负操作原理是把数字字符串先转成数值类型,再执行取负操作,最后再转回字符串,就得到了负数,之后的计算过程相同。


下面再介绍一些特殊的运算——开平方,百分比运算,取倒数。

开平方

num1=parseFloat(str1);
num1=Math.sqrt(num1);
str1=num1.toString();
原理与取负差不多,先把数字字符串先转成数值类型,再调用函数Math.sqrt(num1)执行开方操作,最后再转回字符串。


取倒数

       num1=accDiv("1", str1);
       str1=num1.toString();

取倒数只需用1除以str1就好了(注意应转化为相同的数据类型再做除法)。


百分比运算

这是window自带的计算器中%的功能 :
  1、可以按百分比形式显示乘积结果   
  例:输入一个数,然后点*,在输第二个数,然后按%,比如50*25%最后因该等于12.5   
  2、可以执行带百分号的计算   
  例:输入一个数,然后选+-*/,然后点击%,最后点=号,比如50+25%(其中25%表示为50的25%)最后因该等于62.5

应该注意%的用法,并不是把数字转化为百分比的形式那么简单


除了以上这些基本的计算功能,还可以为计算器加上其他实用的功能,如支持键盘输入,可以记录操作日志等等。这些功能就不一一讲解了,最后附上全部代码

calculator.html

<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Web计算器V1.0</title><link rel="stylesheet" type="text/css" href="calculator.css" /><script type="text/javascript" src="calculate.js"></script><script type="text/javascript">document.onkeypress=keyPress;document.onkeydown=keyDown;</script></head><body><div class="container"><div class="calculate"><div class="calculate base"><p><input type="text" id="disText" value="0"  readonly><table align="center"><tr><td><input type="button" class="button symbol" onclick="back()" id="back" value="<--"></td><td><input type="button" class="button symbol" onclick="clearError(1)" id="CE" value="CE"></td><td><input type="button" class="button symbol" onclick="Clear (1) " id="C" value="C"></td><td><input type="button" class="button symbol" onclick="negative()" id="negative" value="±"></td><td><input type="button" class="button symbol" onclick="square()" id="square" value="√"></td></tr><tr><td><input type="button" class="button number" onclick="input(value)" id="seven" value="7"></td><td><input type="button" class="button number" onclick="input(value)" id="eight" value="8"></td><td><input type="button" class="button number" onclick="input(value)" id="nine" value="9"></td><td><input type="button" class="button symbol" onclick="operation(4)" id="divide" value="/"></td><td><input type="button" class="button symbol" onclick="percent()" id="percent" value="%"></td></tr><tr><td><input type="button" class="button number" onclick="input(value)" id="four" value="4"></td><td><input type="button" class="button number" onclick="input(value)" id="five" value="5"></td><td><input type="button" class="button number" onclick="input(value)" id="six" value="6"></td><td><input type="button" class="button symbol" onclick="operation(3)" id="multiply" value="*"></td><td><input type="button" class="button symbol" onclick="reciprocal()" id="reciprocal" value="1/x"></td></tr><tr><td><input type="button" class="button number" onclick="input(value)" id="one" value="1"></td><td><input type="button" class="button number" onclick="input(value)" id="two" value="2"></td><td><input type="button" class="button number" onclick="input(value)" id="three" value="3"></td><td><input type="button" class="button symbol" onclick="operation(2)" id="subtract" value="-"></td><th rowspan="2"><input type="button" class="button symbol" onclick="equal()" id="equal" value="=" style="height:100px"></th></tr><tr><th colspan="2"><input type="button" class="button number" onclick="input(value)" id="zero" value="0" style="width:103px"></th><td><input type="button" class="button symbol" onclick="input(value)" id="point" value="."></td><td><input type="button" class="button symbol" onclick="operation(1)" id="add" value="+"></td></tr></table></p></div></div><div class="record"><button class="button number" onclick="recordClear()">清空</button> <p id="recText"></p></div> </div></body></html>

calculate.js

var num1 = 0,num2 = 0,op = 0,c = 0;var str = "",str1 ="",str2="",rStr="";   var end = false;function input (a) {if (end&&(!op)) {Clear();record("</br>"+a);}   //检查结束标志,是否继续运算else {record(a);}str1=str1+a;display (a);}function operation (b) {if (!op) {               //检查运算符号是否重复输入op=b;str2=str1;str1="";    switch (op){    case 1:display("+");         //加法标志    record("+");    break;    case 2:display("-")         //减法标志    record("-");    break;    case 3:display("*") //乘法标志    record("*");    break;    case 4:display("/")//除法标志    record("/");    break;}};}function equal () {record("=");if (check(str1)&&check(str2)) {switch (op){case 1:num1=accAdd(str2, str1);break;case 2:num1=accSub(str2, str1);break;case 3:num1=accMul(str2, str1);break;case 4:num1=accDiv(str2, str1);break;}Clear();str1=num1.toString();display(str1);record(str1);end = true;} else{Clear();document.getElementById("disText").value="Error";}}function negative () {record("negative");if(check(str1)){num1=parseFloat(str1);num2=-num1;clearError ();str1=num2.toString();display(str1);}else{Clear();document.getElementById("disText").value="Error";}}function reciprocal () {record("1/x");num1=accDiv("1", str1);clearError ();str1=num1.toString();display(str1);record(str1);end = true;}function square () {record("square");if(check(str1)){num1=parseFloat(str1);num1=Math.sqrt(num1);clearError ();str1=num1.toString();display(str1);record(str1);end = true;}else{Clear();document.getElementById("disText").value="Error";}}function percent () {record("%");if (str2=="") {Clear();} else{num1=accDiv(str1, "100");str1=num1.toString();num1=accMul(str1,str2);clearError();str1=num1.toString();display(str1);record(str1);};}function display (c) {str=str+c;document.getElementById("disText").value=str;}function Clear () {if (c) {record("CE");c=0;};str1 = "";str2 = "";op = 0;str = "";end = false;document.getElementById("disText").value="0";}function clearError (){if (c) {record("CE");c=0;};if (str1=!"") {switch (op){case 0:Clear();break;case 1:str1="";str=str2+"+";display("");break;case 2:str1="";str=str2+"-";display("");break;case 3:str1="";str=str2+"*";display("");break;case 4:str1="";str=str2+"/";display("");break;}}}function back () {record("<--");if (str1=="") {op=0;} else{str1=str1.substring(0,str1.length-1);};str=str.substring(0,str.length-1);display("");}//检查是否为数字(包含正负和小数点)function check (s) {var regu = "^\-?[0-9]+\.?[0-9]*$"; var re = new RegExp(regu); if (re.test(s)) { return true; }else{ return false; }} function keyPress(e){var currKey=0,CapsLock=0,e=e||event;currKey=e.keyCode||e.which||e.charCode;CapsLock=currKey>=65&&currKey<=90;keyName = String.fromCharCode(currKey);switch(keyName){     case "1":input("1");break;   case "2":input("2");break;   case "3":input("3");break;   case "4":input("4");break;   case "5":input("5");break;   case "6":input("6");break;   case "7":input("7");break;   case "8":input("8");break;   case "9":input("9");break;   case "0":input("0");break;   case ".":input(".");break;   case "+":operation(1);break;   case "-":operation(2);break;   case "*":operation(3);break;   case "/":operation(4);break;   case "=":equal();break;}};function keyDown(d){var d=d||vent;var currKey=d.keyCode||d.which||d.charCode;   switch(currKey)   {   case 8:back();break;    case 27:Clear();break;    case 46:clearError();; break;    }}function accDiv(s1, s2) {        var t1 = 0, t2 = 0, r1, r2;        try { t1 = s1.split(".")[1].length } catch (e) { }        try { t2 = s2.split(".")[1].length } catch (e) { }        with (Math) {            r1 = Number(s1.replace(".", ""))            r2 = Number(s2.replace(".", ""))            return (r1 / r2) * pow(10, t2 - t1);        }    }    function accMul(s1, s2) {        var m = 0, s1 = s1.toString(), s2 = s2.toString();        try { m += s1.split(".")[1].length } catch (e) { }        try { m += s2.split(".")[1].length } catch (e) { }        return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)    }    function accAdd(s1, s2) {        var r1, r2, m, c;        try { r1 = s1.split(".")[1].length } catch (e) { r1 = 0 }        try { r2 = s2.split(".")[1].length } catch (e) { r2 = 0 }        c = Math.abs(r1 - r2);        m = Math.pow(10, Math.max(r1, r2))        if (c > 0) {            var cm = Math.pow(10, c);            if (r1 > r2) {                s1 = Number(s1.replace(".", ""));                s2 = Number(s2.replace(".", "")) * cm;            }            else {                s1 = Number(s1.replace(".", "")) * cm;                s2 = Number(s2.replace(".", ""));            }        }        else {            s1 = Number(s1.replace(".", ""));            s2 = Number(s2.replace(".", ""));        }        return (s1 + s2) / m    }    function accSub(s1,s2){    var r1,r2,m,n; try{r1=s1.split(".")[1].length}catch(e){r1=0}    try{r2=s2.split(".")[1].length}catch(e){r2=0}    m=Math.pow(10,Math.max(r1,r2));    //动态控制精度长度n=(r1>=r2)?r1:r2;return ((s1*m-s2*m)/m).toFixed(n);}//记录日志function record (r) {if (r=="="|| r=="1/x" || r=="square" || r=="%") {var r = r + "</br>";}document.getElementById("recText").innerHTML+=r ;}//清空记录function recordClear () {document.getElementById("recText").innerHTML="";r="";}
calculator.css
body{ background: #f5faff;}div.container{width:50%;margin:0 auto;   /*居中*/}div.calculate{width: 296px;border-style: solid;border-color: grey;float: left;}p{text-align: center;}#disText{width: 255px;height: 50px;font-size:xx-large;text-align:right;}#recText{width: 10em;height: 270px;text-align:left;font-size: x-large;overflow:auto;}.button{width: 47px;line-height: 38px;      /*设置行距*/text-align: center;     /*规定文本的水平对齐方式*/font-weight: bold;     border-radius: 5px;margin:0 2px 2px 0;    /*设置所有外边距属性*/position: relative;overflow: hidden;}.button.number{color: #8c96a0;text-shadow:1px 1px 1px #fff;border:1px solid #dce1e6;box-shadow: 0 1px 2px #fff inset,0 -1px 0 #a8abae inset;background: -webkit-linear-gradient(top,#f2f3f7,#e4e8ec);background: -moz-linear-gradient(top,#f2f3f7,#e4e8ec);background: linear-gradient(top,#f2f3f7,#e4e8ec);}.button.number:hover     /*添加悬停效果*/{background: -webkit-linear-gradient(top,#fefefe,#CCCCCC);background: -moz-linear-gradient(top,#f2f3f7,#CCCCCC);background: linear-gradient(top,#f2f3f7,#CCCCCC);}.button.number:active     /*点击后效果*/{top:1px;box-shadow: 0 1px 3px #a8abae inset,0 3px 0 #fff;background: -webkit-linear-gradient(top,#e4e8ec,#e4e8ec);background: -moz-linear-gradient(top,#e4e8ec,#e4e8ec);background: linear-gradient(top,#e4e8ec,#e4e8ec);}.button.symbol{color: #f2f3f7;border:1px solid #333;box-shadow: 0 1px 2px #8b8b8b inset,0 -1px 0 #3d3d3d inset,0 -2px 3px #8b8b8b inset;background: -webkit-linear-gradient(top,grey,#4c4c4c);background: -moz-linear-gradient(top,grey,#4a4a4a);background: linear-gradient(top,grey,#4a4a4a);}.button.symbol:hover{background: -webkit-linear-gradient(top,#999999,#575757);background: -moz-linear-gradient(top,#999999,#575757);background: linear-gradient(top,#999999,#575757);}.button.symbol:active{top:1px;box-shadow: 0 1px 3px #111 inset,0 3px 0 #fff;background: -webkit-linear-gradient(top,#424242,#575757);background: -moz-linear-gradient(top,#424242,#575757);background: linear-gradient(top,#424242,#575757);}div.base{width: 270px;margin:10px 10px 10px 10px; border-style: solid;}div.record{width: 250px;margin-left:310px;border: solid gray;padding:10px;/*background: url(p1.jpg) no-repeat top left;*/}



0 0
原创粉丝点击