html实现科学计算器
做计算器的时候是为了交作业,也参考了一些大佬的作品,交了作业很久才来整理博客,也不太记得具体参考了那一位大佬的,如有冒犯,请联系本人删除。
- 计算器主界面分为普通计算器和科学计算器两种,可以随便切换
- 普通计算器
3. 科学计算器
4. 项目目录
5. index.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
<title>Calculator</title>
<link rel="stylesheet" href="style/css/main.css"/>
<script defer="defer" src="js/gamma.js"></script>
<script defer="defer" src="js/calculator.js"></script>
<script defer="defer" src="js/core.js"></script>
</head>
<body>
<div id="display"><textarea readonly="readonly" disabled="disabed" ></textarea><div></div></div>
<div id="panel">
<div class="key_column2">
<a value="" href="kcalculator.html" data-type="value">科学</a>
<a class="num" value="7" data-type="value">7</a>
<a class="num" value="4" data-type="value">4</a>
<a class="num" value="1" data-type="value">1</a>
<a class="num" value="+/-" data-type="command">+/-</a>
</div>
<div class="key_column2">
<a value="C" data-type="command">C</a>
<a class="num" value="8" data-type="value">8</a>
<a class="num" value="5" data-type="value">5</a>
<a class="num" value="2" data-type="value">2</a>
<a class="num" value="0" data-type="value">0</a>
</div>
<div class="key_column2">
<a value="<" id="backspace" data-type="command" ><</a>
<a class="num" value="9" data-type="value" >9</a>
<a class="num" value="6" data-type="value" >6</a>
<a class="num" value="3" data-type="value" >3</a>
<a class="num" value="." data-type="value">.</a>
</div>
<div class="key_column2">
<a class="" value="÷" id="add" data-type="operator">÷</a>
<a class="" value="x" id="multiply" data-type="operator">x</a>
<a value="-" id="subtract" data-type="operator">-</a>
<a value="+" id="divide" data-type="operator">+</a>
<a value="=" data-type="command" >=</a>
</div>
</div>
</body>
</html>
- kcalculator代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
<title>Calculator</title>
<link rel="stylesheet" href="style/css/kcalculator.css"/>
<script defer="defer" src="js/gamma.js"></script>
<script defer="defer" src="js/calculator.js"></script>
<script defer="defer" src="js/core.js"></script>
</head>
<body>
<div id="display"><textarea readonly="readonly" disabled="disabed" ></textarea><div></div></div>
<div id="panel">
<div class="block1">
<div class="key_column">
<a value="" href="index.html" data-type="value">普通</a>
<a class="small" value="sin(" data-type="operator">sin</a>
<a class="small" value="ln(" data-type="operator">ln</a>
<a class="sup" value="^2" data-type="operator"><p>x<sup>2</sup></p></a>
<a class="" value="(" data-type="command">(</a>
</div>
<div class="key_column">
<a class="" value="√(" data-type="operator">√</a>
<a class="small" value="cos(" data-type="operator">cos</a>
<a class="small" value="log(" data-type="operator">log</a>
<a class="sup" value="^" data-type="operator"><p>x<sup>y</sup></p></a>
<a class="" value=")" data-type="command">)</a>
</div>
<div class="key_column">
<a class="" value="%" data-type="operator">%</a>
<a class="small" value="tan(" data-type="operator">tan</a>
<a class="small" value="1÷(" data-type="operator">1/x</a>
<a class="" value="e" data-type="specialValue">e</a>
<a class="" value="π" data-type="specialValue">π</a>
</div>
</div>
<div class="block2">
<div class="key_column2">
<a class="small" value="!" data-type="operator" >X!</a>
<a class="num" value="7" data-type="value">7</a>
<a class="num" value="4" data-type="value">4</a>
<a class="num" value="1" data-type="value">1</a>
<a class="num" value="+/-" data-type="command">+/-</a>
</div>
<div class="key_column2">
<a value="C" data-type="command">C</a>
<a class="num" value="8" data-type="value">8</a>
<a class="num" value="5" data-type="value">5</a>
<a class="num" value="2" data-type="value">2</a>
<a class="num" value="0" data-type="value">0</a>
</div>
<div class="key_column2">
<a value="<" id="backspace" data-type="command" ><</a>
<a class="num" value="9" data-type="value" >9</a>
<a class="num" value="6" data-type="value" >6</a>
<a class="num" value="3" data-type="value" >3</a>
<a class="num" value="." data-type="value">.</a>
</div>
<div class="key_column2">
<a class="" value="÷" id="add" data-type="operator">÷</a>
<a class="" value="x" id="multiply" data-type="operator">x</a>
<a value="-" id="subtract" data-type="operator">-</a>
<a value="+" id="divide" data-type="operator">+</a>
<a value="=" data-type="command" >=</a>
</div>
</div>
</div>
</body>
</html>
- mian.css
html, body {
margin: 0;
padding: 0;
height: 100%;
line-height: 100%;
overflow: hidden;
font-size: 10px;
font-weight: normal;
background-color: whitesmoke;
-moz-user-select: none;
}
.block2 {
display: flex;
background-color: whitesmoke;
vertical-align: top;
width: 100%;
height: 100%;
-moz-user-select: none;
}
.key_column2 {
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
width: 100%;
height: 100%;
align-items: center;
-moz-user-select: none;
}
a{
list-style: none;
/* text nodes in the source code affect the layout */
margin-right: -2px;
background: transparent;
border: 0;
vertical-align: top;
border-radius: 0;
height: 19%;
background: white;
width: 80%;
height: 16%;
color: black;
box-shadow: 2px 1px 1px rgba(0,0,0,0.4),-2px 1px 1px rgba(0,0,0,0.3);
text-align: center;
text-align: center;
justify-content: space-around;
align-items: center;
display: flex;
cursor: pointer;
font-family: "sans serif";
text-decoration: none;
}
a {
margin-right: -2px;
background: transparent;
border: 0;
vertical-align: top;
border-radius: 0;
height: 19%;
font-size: 3.5rem;
background: white;
width: 80%;
height: 14%;
color: black;
box-shadow: 2px 1px 1px rgba(0,0,0,0.4),-2px 1px 1px rgba(0,0,0,0.3);
border-radius: 50px
}
a[disabled] {
pointer-events: none;
}
.num a{
font-size: 3rem;
font-weight: 200;
color: #e7e7e7;
border-top: .1rem solid #191919;
border-right: .1rem solid #191919;
}
a.small{
font-size: 2.3rem;
font-weight: 500;
}
a[value="C"]{
font-size: 3.3rem;
font-weight: 500;
border-right: .1rem solid #191919;
}
a[value="="]{
background-color: orangered;
}
a[value=""]{
background-color: deepskyblue;
}
a::-moz-focus-inner {
padding: 0;
margin: 0;
border: 0
}
/* Result Display */
#display {
color: black;
background-color: whitesmoke;
height: 15.6rem;
line-height: 15.6rem;
width: 32rem;
position: relative;
}
#display div {
transform-origin: right center;
position: absolute;
right: 3rem;
height: calc((100% / 3) * 2);
line-height: 136px;
vertical-align: middle;
font-weight: 200;
font-size: 8.2rem;
}
#display textarea{
display: block;
width: 100%;
background: transparent;
height: calc(100%/3);
border: none;
text-align: right;
resize:none;
color: black;
font-size: 3.2rem;
overflow: hidden;
cursor: pointer;
}
#panel{
width: 100%;
height: calc((100% / 3) * 2);
display: flex;
flex-flow: row;
}
.sup p{
font-size: 2.5rem;
line-height: 2.4rem;
height: 3.2rem;
}
.sup sup{
font-size: 1.5rem;
}
@media (orientation: landscape) {
.block1{
display: flex;
}
.block2{
width: calc((100%/7)*4);
}
a,a[value="C"]{
font-size: 2.3rem;
}
#display div {
line-height: 62px;
vertical-align: middle;
}
}
#display {
width: 100%;
height: calc(100% / 3);
}
@media(max-width:480px) and (orientation: landscape){
a{
width:90%;
height:16%;
}
}
input:active,
input.active,
.active {
background-color: black;
}
a:active,
a.active,
.active {
margin-right: -3px;
background-color: whitesmoke;
}
- kcalculator.css
html, body {
margin: 0;
padding: 0;
height: 100%;
line-height: 100%;
overflow: hidden;
font-size: 10px;
font-weight: normal;
background-color: white;
-moz-user-select: none;
}
.block1 {
background-color: white;
vertical-align: top;
width: calc((100%/7)*3);
height: 100%;
display: none;
-moz-user-select: none;
}
.block2 {
display: flex;
background-color: white;
vertical-align: top;
width: 100%;
height: 100%;
-moz-user-select: none;
}
.key_column {
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
width: calc(100%/3);
height: 100%;
align-items: center;
-moz-user-select: none;
}
.key_column2 {
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
width: 25%;
height: 100%;
align-items: center;
-moz-user-select: none;
}
a{
list-style: none;
margin-right: -2px;
border: 0;
vertical-align: top;
border-radius: 0;
background: white;
width: 80%;
height: 16%;
color: black;
box-shadow: 2px 1px 1px rgba(0,0,0,0.4),-2px 1px 1px rgba(0,0,0,0.3);
text-align: center;
justify-content: space-around;
align-items: center;
display: flex;
cursor: pointer;
text-decoration: none;
}
a {
margin-right: -2px;
background: transparent;
border: 0;
vertical-align: top;
border-radius: 0;
height: 19%;
font-size: 3.5rem;
background: white;
width: 80%;
height: 14%;
color: black;
box-shadow: 2px 1px 1px rgba(0,0,0,0.4),-2px 1px 1px rgba(0,0,0,0.3);
border-radius: 50px
}
a[disabled] {
pointer-events: none;
}
.num a{
font-size: 3rem;
font-weight: 200;
color: #e7e7e7;
border-top: .1rem solid #191919;
border-right: .1rem solid #191919;
}
a[value="="]{
background-color: orangered;
}
a[value=""]{
background-color: deepskyblue;
}
a.small{
font-size: 2.3rem;
font-weight: 500;
}
a[value="C"]{
font-size: 3.3rem;
font-weight: 500;
border-right: .1rem solid #191919;
}
a[value="<"]{
/*background: url(images/icon_backspace.png) center no-repeat;*/
/*color: transparent;*/
}
a::-moz-focus-inner {
padding: 0;
margin: 0;
border: 0
}
/* Result Display */
#display {
color: black;
background-color: whitesmoke;
height: 15.6rem;
line-height: 15.6rem;
width: 32rem;
position: relative;
}
#display div {
transform-origin: right center;
position: absolute;
right: 3rem;
height: calc((100% / 3) * 2);
line-height: 136px;
vertical-align: middle;
font-weight: 200;
font-size: 8.2rem;
}
#display textarea{
display: block;
width: 100%;
background: transparent;
height: calc(100%/3);
border: none;
text-align: right;
resize:none;
color: black;
font-size: 3.2rem;
overflow: hidden;
cursor: pointer;
}
#panel{
width: 100%;
height: calc((100% / 3) * 2);
display: flex;
flex-flow: row;
}
.sup p{
font-size: 2.5rem;
line-height: 2.4rem;
height: 3.2rem;
}
.sup sup{
font-size: 1.5rem;
}
@media (orientation: landscape) {
.block1{
display: flex;
}
.block2{
width: calc((100%/7)*4);
}
a,a[value="C"]{
font-size: 2.3rem;
}
#display div {
line-height: 62px;
vertical-align: middle;
}
}
#display {
width: 100%;
height: calc(100% / 3);
}
@media(max-width:480px) and (orientation: landscape){
a{
width:90%;
height:16%;
}
}
input:active,
input.active,
.active {
background-color: black;
}
a:active,
a.active,
.active {
margin-right: -3px;
background-color: whitesmoke;
}
- calculator.js
'use strict';
var Calculator = {
display: document.querySelector('#display textarea'),
displayResult:document.querySelector('#display div'),
significantDigits: 11,
result: '',
currentInputOperator:'',
currentInput: '',
lastOperator:'',
inputDigits: 0,
decimalMark: false,
isNegative: false,
canAppendOperate:function(){
return this.currentInputOperator==')'||this.currentInputOperator == '^2'||this.currentInputOperator == '!';
},
scrollDisplay:function scrollDisplay(){
this.display.scrollTop = this.display.scrollHeight;
},
updateDisplay: function updateDisplay() {
var value = this.currentInput || this.result.toString();
var infinite = new RegExp((1 / 0) + '', 'g');
var outval = value.replace(infinite, '∞').replace(NaN, 'Error');
this.displayResult.textContent = outval;
var screenWidth = this.displayResult.parentNode.offsetWidth - 60;
var valWidth = this.displayResult.offsetWidth;
var scaleFactor = Math.min(1, screenWidth / valWidth);
//this.display.style.MozTransform = 'scale(' + scaleFactor + ')';
// Work around for bug #989403
this.displayResult.style.fontSize = 5.5 * scaleFactor + 'rem';
},
appendDigit: function appendDigit(value) {
if (this.inputDigits + 1 > this.significantDigits ||
(this.currentInput === '0' && value === '0')) {
return;
}
if (value === '.') {
if (this.decimalMark) {
return;
} else {
this.decimalMark = true;
}
if (!this.currentInput) {
this.currentInput += '0';
this.display.value += '0';
}
} else {
if (this.currentInput === '0' && value !== '0') {
this.currentInput = '';
this.display.value = this.display.value.substring(0,this.display.value.length-1);
}
++this.inputDigits;
}
this.currentInput += value;
this.display.value += value;
this.updateDisplay();
},
clearInput: function clearInput() {
this.currentInput = '';
this.currentInputOperator = '';
this.result = 0;
this.inputDigits = 0;
this.decimalMark = false;
this.isNegative = false;
this.updateDisplay();
this.display.value = '';
},
init: function init() {
document.addEventListener('mousedown', this);
document.addEventListener('touchstart', function(evt){
var target = evt.target;
if ((target.dataset.type == "value") || (target.value == "C") || (target.value == "=")) {
target.classList.add("active");
}
});
document.addEventListener('touchend', function(evt){
var target = evt.target;
if ((target.dataset.type == "value") || (target.value == "C") || (target.value == "=")) {
target.classList.remove("active");
}
});
this.updateDisplay();
this.display.value = '';
},
handleOperator:function(value){
switch (value){
case '+':
case '-':
case '÷':
case '!':
case '%':
case '^':
case 'x':
if (value === this.currentInputOperator||this.currentInputOperator=='u') {
return;
}else if(!this.currentInputOperator&&!this.currentInput){
if(!this.result)
return;
this.display.value = this.result+value;
this.result = '';
}else if(this.currentInputOperator&&this.currentInputOperator!='u'&&!this.canAppendOperate()) {
this.display.value = this.display.value.replace(/.$/, value);
}else{
this.display.value += value;
}
this.currentInputOperator= value;
break;
case '^2':
if(!this.currentInputOperator&&!this.currentInput&&this.result){
this.display.value = this.result+value;
}else if(this.currentInput||this.currentInputOperator==')'){
this.display.value += value;
}
this.currentInputOperator = value;
break;
default :
if(!this.currentInputOperator&&!this.currentInput){
this.display.value = (this.result?this.result+'x':'') +value;
}else if(this.currentInputOperator=='!'||this.currentInputOperator==')'){
this.display.value += 'x'+value;
}else if(this.currentInputOperator){
this.display.value += value;
}else{
this.display.value += 'x'+value;
}
this.currentInputOperator = 'u';
break;
}
this.currentInput = '';
this.inputDigits = 0;
this.decimalMark = false;
this.lastOperator = value;
this.result = '';
},
toFixed:function(val){
val += '';
if(val.indexOf('e')>0){
val = val.replace(/([0-9\.]+)e/,function(str,num){
return parseFloat(num).toFixed(2)+'E';
})
return val;
}
var pos = val.indexOf('.');
if(pos > 0){
if(val.length-pos-1>6){
val = parseFloat(val).toFixed(6);
val += '';
pos = val.indexOf('.');
if(val[pos+1]=='0'&&val[pos+2]=='0'&&val[pos+3]=='0'&&val[pos+4]=='0'){
val = parseFloat(val).toFixed(0);
}
}
}else{
pos = val.length;
}
if(pos>10){
val = parseFloat(val).toFixed(pos-3);
val += '';
val = val[0]+'.'+val[1]+val[2]+'E+'+(pos-1);
}
return val;
},
handleCommand:function handleCommand(value){
switch (value) {
case '=':
if (this.display.value&&(this.currentInput||this.currentInputOperator.match(/[0-9\)!]$/))) {
this.result = core.calculate(this.display.value);
this.display.value += '=';
this.currentInput = '';
this.currentInputOperator = '';
this.inputDigits = 0;
this.decimalMark = false;
this.isNegative = false;
if(core.isError){
this.updateDisplay();
this.result = '';
}else{
this.result = this.toFixed(this.result);
this.updateDisplay();
}
core.clear();
}
break;
case '(':
if(this.currentInput||this.canAppendOperate()){
return;
}else if(!this.currentInput&&!this.currentInputOperator){
this.clearInput();
}
this.display.value += '(';
this.currentInputOperator = 'u';
this.currentInput = "";
break;
case ')':
if(!this.currentInputOperator&&!this.currentInput){
return;
}
this.display.value += ')';
this.currentInputOperator = ')';
this.currentInput ='';
break;
case 'C':
this.clearInput();
break;
case '<': /* backspace */
if(this.currentInput === '') {
return;
} else {
if(this.currentInput.slice(-1) === '.') {
this.currentInput = this.currentInput.substring(0, this.currentInput.length-1);
this.decimalMark = false;
this.updateDisplay();
return;
}else if(this.isNegative&&this.currentInput.slice(-1) === '-') {
this.display.value = this.display.value.substring(0, this.display.value.length-3);
this.currentInput = '';
this.isNegative = false;
this.updateDisplay();
return;
}else if(this.isNegative&&this.display.value.slice(-1) === ')'){
this.display.value = this.display.value.substring(0, this.display.value.length-2)+')';
this.currentInput = this.currentInput.substring(0, this.currentInput.length-1);
--this.inputDigits;
this.updateDisplay();
return;
}
this.display.value = this.display.value.substring(0, this.display.value.length-1);
this.currentInput = this.currentInput.substring(0, this.currentInput.length-1);
--this.inputDigits;
if(this.inputDigits==0){
this.currentInputOperator = this.lastOperator;
}
}
this.updateDisplay();
break;
case '+/-':
if(!this.inputDigits)
return;
if(this.isNegative) {
this.currentInput = this.currentInput.slice(1);
this.display.value = this.display.value.replace(new RegExp('\\(\\-[0-9.]+\\)$','g'),this.currentInput);
} else {
this.currentInput = '-' + this.currentInput+'';
this.display.value = this.display.value.replace(new RegExp('[0-9.]+$','g'),'('+this.currentInput+')');
}
this.isNegative = !this.isNegative;
this.updateDisplay();
break;
}
},
handleEvent: function handleEvent(evt) {
var target = evt.target;
var targetName = target.nodeName.toLowerCase();
if(targetName == 'p'){
target = target.parentNode;
}else if(targetName == 'sup'){
target = target.parentNode.parentNode;
}
var value = target.getAttribute('value');
switch (target.dataset.type) {
case 'value':
if(this.result){
this.result = '';
}
if(!this.currentInputOperator&&!this.currentInput)
this.display.value="";
else if(this.currentInput=='s'||this.canAppendOperate()){
return;
}
this.appendDigit(value);
this.currentInputOperator = '';
break;
case 'specialValue':
if(this.currentInput||this.canAppendOperate()){ return;}
else if(!this.currentInputOperator&&!this.currentInput) {this.clearInput();}
this.display.value += value;
this.currentInput = 's';
break;
case 'operator':
this.handleOperator(value);
break;
case 'command':
this.handleCommand(value);
break;
}
this.scrollDisplay();
}
};
// String concatenation then number subtraction
Calculator.maxDisplayableValue = '1e' + Calculator.significantDigits - 1;
window.addEventListener('load', function load(evt) {
window.removeEventListener('load', load);
Calculator.init();
});
- core.js
'use strict';
var core={
maxN:0,
isError:false,
errorResult:'Error',
specialCalculateExp: new RegExp('(tan|cos|sin|log|ln|√)([-]?[0-9\\.]+(E[\\+\\-][0-9]+)?)','g'),
factorialExp:new RegExp('([\\+\\-\\*%\/]?[-]?)([0-9\\.]+(E[\\+\\-][0-9]+)?)!','g'),
powExp:new RegExp('([\\+\\-\\*%\/]?[-]?)([0-9\\.]+)\\^([-]?[0-9\\.]+)','g'),
secondPriorityOperator:new RegExp('[-]?[0-9\\.]+(E[\\+\\-][0-9]+)?([\\+\\-][-]?[0-9\\.]+(E[\\+\\-][0-9]+)?)+','g'),
secondPrioritySingleOperator:new RegExp('[\\+\\-][-]?[0-9\\.]+(E[\\+\\-][0-9]+)?','g'),
firstPriorityOperator:new RegExp('[-]?[0-9\\.]+(E[\\+\\-][0-9]+)?([\\*\\/%][-]?[0-9\\.]+(E[\\+\\-][0-9]+)?)+','g'),
firstPrioritySingleOperator:new RegExp('[\\*\\/%][-]?[0-9\\.]+(E[\\+\\-][0-9]+)?','g'),
firstPriorityResult:null,
secondPriorityResult:null,
testResult:function(str){
str = str+'';
if(str.indexOf('NaN')>-1){
this.isError = true;
this.errorResult='Error';
return true;
}else if(str.indexOf('Infinity')>-1){
this.isError = true;
this.errorResult='∞';
return true;
}
return false;
},
showError:function(f,msg){
console.error("core.js error: "+msg+" when it calculate "+f);
},
getCalculatorExp:function(){
if(this.maxN<1) return null;
return new RegExp("((tan|cos|sin|log|ln|√)?[-]?[0-9\\.!]+(E[\\+\\-][0-9]+)?([\\+\\-\\*%\/\\^](tan|cos|sin|log|ln|√)?[-]?[0-9\\.!]+(E[\\+\\-][0-9]+)?)*)(?=<\/b"+this.maxN+">)",'g');
},
clear:function(){
this.maxN = 0;
this.isError = false;
this.errorResult = 'Error';
this.firstPriorityResult = null;
this.secondPriorityResult = null;
},
/**
* get calculated result with the input string
* @param {string} the input string which need calculate
* @return {string} get calculated result
*/
calculate:function(blockStr){
var str = this.getBrak(blockStr);
var calculatorExp = null;
//get e,π
str = str.replace(/e/g,Math.E);
str = str.replace(/π/g,Math.PI);
str = str.replace(/x/g,'*');
str = str.replace(/÷/g,'/');
var isEmpty;
while(calculatorExp = this.getCalculatorExp()){
isEmpty = true;
str = str.replace(calculatorExp,function(calculatorString){
if(core.isError) return calculatorString;
isEmpty = false;
if(calculatorString&&calculatorString!=""){
return core.calculateWithoutBracket(calculatorString);
}
return calculatorString;
});
if(this.isError) {return this.errorResult;}
if(isEmpty){
this.isError = true;
this.errorResult='Error';
this.showError(blockStr,'there is nothing in the brackets');
return this.errorResult;
}
//clear bracket
str = str.replace(new RegExp("(<b"+this.maxN+">|<\\/b"+this.maxN+">)",'g'),'');
this.maxN--;
}
str = this.calculateWithoutBracket(str);
if(this.isError) {return this.errorResult;}
return str;
},
//make <bN> to replace brackets
getBrak:function(str){
var temp = str;
if(!str)
return null;
var N=0;
str = str.replace(/(\(|\))/g,function($0,$1){
if($1=="("){ N++; core.maxN = (N>core.maxN)?N:core.maxN; return "<b"+N+">"; }
if($1==")"){
$0 = "</b"+(N--)+">";
if(N<0){
core.isError = true;
core.showError(temp,'the number of brackets is error');
}
return $0;
}
});
if(N!=0){
this.isError = true;
this.showError(temp,'the number of brackets is error')
}
return str;
},
calculateWithoutBracket:function(str){
var blockStr = str;
str = this.preCalculate(str);
if(str.indexOf('^')>-1){
core.isError = true;
core.showError(blockStr,'too many "^", you need use brackets');
return str;
}
if(this.isError) {return str;}
str = str.replace(this.firstPriorityOperator,function(calculatorString){
return core.getFirstPriorityCalculatedResult(calculatorString);
});
if(this.isError) {return str;}
str = str.replace(this.secondPriorityOperator,function(calculatorString){
return core.getSecondPriorityCalculatedResult(calculatorString);
});
return str;
},
preCalculate:function(str){
str = str.replace(this.specialCalculateExp,function(calculatorString,operator,num){
var specialResult = '';
switch (operator){
case 'tan':
specialResult = Math.tan(num*0.017453293);
break ;
case 'sin':
specialResult = Math.sin(num*0.017453293);
break;
case 'cos':
specialResult = Math.cos(num*0.017453293);
break;
case 'log':
specialResult = Math.log10(num);
break;
case 'ln':
specialResult = Math.log(num);
break;
case '√':
specialResult = Math.sqrt(num);
break;
default :
return calculatorString;
}
specialResult +='';
if(core.testResult(specialResult)){
core.showError(calculatorString,"");
}
return specialResult;
});
//calculate factorial
str = str.replace(this.factorialExp,function(calculatorString,operator,num,E,pos){
if(operator.length==2||(pos === 0 && operator==='-')){
core.isError = true;
core.showError('-'+num+'!','factorial does not support a negative');
return calculatorString;
}
var _factorial = factorial(num)+'';
if(core.testResult(_factorial)) {
core.showError(num + '!', 'factorial result is too large');
}
return operator+ _factorial;
});
//calculate x^y
str = str.replace(this.powExp,function(calculatorString,operator,x,y){
if(operator.length==2){ x= '-'+x;operator='-';}
var _pow = Math.pow(x,y)+'';
if(core.testResult(_pow)){
core.showError(calculatorString,'Math.pow result is too large');
}
return operator+_pow;
});
return str;
},
getFirstPriorityCalculatedResult:function(str){
this.firstPriorityResult = str.match(/^[-]?[0-9\\.]+(E[\\+\\-][0-9]+)?/)[0];
str.replace(this.firstPrioritySingleOperator,function(calculatorString){
switch(calculatorString[0]){
case '*':
core.firstPriorityResult = core.firstPriorityResult *calculatorString.substring(1,calculatorString.length);
break;
case '/':
core.firstPriorityResult = core.firstPriorityResult /calculatorString.substring(1,calculatorString.length);
break;
case '%':
core.firstPriorityResult = core.firstPriorityResult %calculatorString.substring(1,calculatorString.length);
break;
default :
break;
}
if(core.testResult(core.firstPriorityResult)){
core.showError(calculatorString,calculatorString[0] + ' error');
}
return calculatorString;
});
return this.firstPriorityResult;
},
getSecondPriorityCalculatedResult:function(str){
this.secondPriorityResult = str.match(/^[-]?[0-9\\.]+(E[\\+\\-][0-9]+)?/)[0];
str.replace(this.secondPrioritySingleOperator,function(calculatorString,minStr,index){
if(index==0)
return calculatorString;
switch(calculatorString[0]){
case '+':
core.secondPriorityResult = parseFloat(core.secondPriorityResult) +parseFloat(calculatorString.substring(1,calculatorString.length));
break;
case '-':
core.secondPriorityResult = core.secondPriorityResult -calculatorString.substring(1,calculatorString.length);
break;
default :
break;
}
if(core.testResult(core.secondPriorityResult)){
core.showError(calculatorString,calculatorString[0] + ' error');
}
return calculatorString;
});
return this.secondPriorityResult;
}
};
- gamma.js
var g = 7;
var p = [
0.99999999999980993,
676.5203681218851,
-1259.1392167224028,
771.32342877765313,
-176.61502916214059,
12.507343278686905,
-0.13857109526572012,
9.9843695780195716e-6,
1.5056327351493116e-7
];
var g_ln = 607/128;
var p_ln = [
0.99999999999999709182,
57.156235665862923517,
-59.597960355475491248,
14.136097974741747174,
-0.49191381609762019978,
0.33994649984811888699e-4,
0.46523628927048575665e-4,
-0.98374475304879564677e-4,
0.15808870322491248884e-3,
-0.21026444172410488319e-3,
0.21743961811521264320e-3,
-0.16431810653676389022e-3,
0.84418223983852743293e-4,
-0.26190838401581408670e-4,
0.36899182659531622704e-5
];
// Spouge approximation (suitable for large arguments)
function lngamma(z) {
if(z < 0) return Number('0/0');
var x = p_ln[0];
for(var i = p_ln.length - 1; i > 0; --i) x += p_ln[i] / (z + i);
var t = z + g_ln + 0.5;
return .5*Math.log(2*Math.PI)+(z+.5)*Math.log(t)-t+Math.log(x)-Math.log(z);
}
function gamma (z) {
if (z < 0.5) {
return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
}
else if(z > 100) return Math.exp(lngamma(z));
else {
z -= 1;
var x = p[0];
for (var i = 1; i < g + 2; i++) {
x += p[i] / (z + i);
}
var t = z + g + 0.5;
return Math.sqrt(2 * Math.PI)
* Math.pow(t, z + 0.5)
* Math.exp(-t)
* x
;
}
};
var factorial = function factorial(z){
if(0==z){
return 1;
}
return z*factorial(z-1);
};