html实现科学计算

计算器的时候是为了交作业,也参考了一些大佬的作品,交了作业很久才来整理博客,也不太记得具体参考了那一位大佬的,如有冒犯,请联系本人删除。

  1. 计算器主界面分为普通计算器和科学计算器两种,可以随便切换
  2. 普通计算

在这里插入图片描述
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>

  1. 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>

  1. 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;
}
  1. 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;
}

  1. 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();
});

  1. 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;
	}
};


  1. 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);
};
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐