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;*/}
- 8.4 如何用JS写计算器
- 如何用JS写九九乘法表
- 如何用js写选项卡
- 如何用js写九九乘法口诀表
- 如何用cfree编写计算器
- 如何用js写一个消息提示中心
- 如何用js写一个简易选项卡
- 如何用vue.js写购物车功能
- 如何用写英语Email
- 如何用英文写证明书
- 如何用英文写请假条
- 如何用verilog写testbench
- 如何用english写EMAIL
- 如何用googletest写单元测试
- 如何用googletest写单元测试
- 如何用邮箱写博客
- 如何用gitbook写书
- 如何用googletest写单元测试
- hollister pas cher soldes saw someone singing
- Android高手的六大境界
- tn nike pas cher and they are the same age fellow worthy of their admiration
- ZOJ 3686-A Simple Tree Problem (DFS+线段树)
- hogan outlet 2014 All Rights Reserved
- 8.4 如何用JS写计算器
- ssh-keygen 免交互, ssh首次交互免输入yes
- hollister pas cher but Wang and Han Yan found that the kidnappers call not hit the Wang family.
- HDU 1087 Super Jumping! Jumping! Jumping! 最大子序列的和
- scarpe hogan outlet this anomaly is similar to alcoholics and drug addicts strikingly abnormal brai
- CSS web页面自适应屏幕
- leetcode Reverse Words in a String
- u-boot.lds分析
- neutron SDN的实现