javaScript简单四则运算工具类ElementaryArithmeticUtils

来源:互联网 发布:自己如何关闭淘宝店铺 编辑:程序博客网 时间:2024/06/01 13:26
ElementaryArithmeticUtils = {//运算符优先级operatorPrecedence: {'+': 0,'-': 0,'*': 1,'×': 1,'÷': 1,'\/': 1},//运算符operator: {'+': '+','-': '-','*': '*','×': '*','÷': '/','\/': '/'},//加法add: function(operandLeft, operandRight) {var operand1 = operandLeft.toString();var operand2 = operandRight.toString();var decimalPlace1 = operand1.indexOf('.') >= 0 ? operand1.split('.')[1].length : 0;var decimalPlace2 = operand2.indexOf('.') >= 0 ? operand2.split('.')[1].length : 0;var multiple = Math.pow(10, Math.max(decimalPlace1, decimalPlace2));return(operandLeft * multiple + operandRight * multiple) / multiple;},//减法subtract: function(operandLeft, operandRight) {var operand1 = operandLeft.toString();var operand2 = operandRight.toString();var decimalPlace1 = operand1.indexOf('.') >= 0 ? operand1.split('.')[1].length : 0;var decimalPlace2 = operand2.indexOf('.') >= 0 ? operand2.split('.')[1].length : 0;var multiple = Math.pow(10, Math.max(decimalPlace1, decimalPlace2));//toFixed避免多出来小数位,如 11.3-10.12000=1.1800000000000015var decimalPlace = (decimalPlace1 >= decimalPlace2) ? decimalPlace1 : decimalPlace2;return((operandLeft * multiple - operandRight * multiple) / multiple).toFixed(decimalPlace);},//乘法multiply: function(operandLeft, operandRight) {var operand1 = operandLeft.toString();var operand2 = operandRight.toString();var decimalPlace1 = operand1.indexOf('.') >= 0 ? operand1.split('.')[1].length : 0;var decimalPlace2 = operand2.indexOf('.') >= 0 ? operand2.split('.')[1].length : 0;var multiple1 = Math.pow(10, decimalPlace1);var multiple2 = Math.pow(10, decimalPlace2);return((operandLeft * multiple1) * (operandRight * multiple2)) / Math.pow(10, decimalPlace1 + decimalPlace2);},//除法divide: function(operandLeft, operandRight) {var operand1 = operandLeft.toString();var operand2 = operandRight.toString();var decimalPlace1 = operand1.indexOf('.') >= 0 ? operand1.split('.')[1].length : 0;var decimalPlace2 = operand2.indexOf('.') >= 0 ? operand2.split('.')[1].length : 0;var multiple1 = Math.pow(10, decimalPlace1);var multiple2 = Math.pow(10, decimalPlace2);return((operandLeft * multiple1) / (operandRight * multiple2)) * Math.pow(10, decimalPlace2 - decimalPlace1);},//校验表达式的合法性isArithmeticExpression: function(expression) {try {expression = expression.replace(/÷/g, '/').replace(/×/g, '*');var result = eval(expression);} catch(e) {return false;}return true;},//计算calculate: function(expression) {var value = eval(expression);return value;},//中缀表达式转后缀表达式infixToPostfixExpression: function(expression) {expression = Bee.StringUtils.deleteWhitespace(expression);expression = this.eliminatePositiveOrNegativeSign(expression);var operatorStack = [];var resultStack = [];var elementArr = expression.match(/[-+\/÷*×()]|(?:[1-9]\d*|0)(?:\.\d+)?/g);var size = elementArr.length;for(var i = 0; i < size; i++) {if(Bee.StringUtils.isNumeric(elementArr[i])) {//如果是数值resultStack.push(elementArr[i]);} else {//操作符栈顶元素var operatorStackTopElement = operatorStack.length === 0 ? '' : operatorStack[operatorStack.length - 1];//运算符if(operatorStack.length === 0 || elementArr[i] === '(' || operatorStackTopElement === '(' || this.operatorPrecedence[elementArr[i]] > this.operatorPrecedence[operatorStackTopElement]) {//操作符栈为空或栈顶元素为右括号')',或操作符的优先级比栈顶运算符高或相等,直接入栈operatorStack.push(elementArr[i]);} else {//如果是右括号")",则依次弹出操作符栈顶的运算符,并压入结果栈,直到遇到左括号'('为止,左右括号不压入结果栈;if(elementArr[i] === ')') {for(var index = operatorStack.length - 1; index >= 0; index--) {if(operatorStack[index] === '(') {operatorStack.pop();break;} else {resultStack.push(operatorStack.pop());}}} else {//将符号栈顶的运算符弹出并压入到结果栈中,再次与符号栈中新的栈顶运算符相比较resultStack.push(operatorStack.pop());i--;continue;}}}}//处理操作符栈剩余的符号if(operatorStack.length > 0) {for(var j = operatorStack.length - 1; j >= 0; j--) {resultStack.push(operatorStack.pop());}}//结果返回return resultStack.join(' ');},//中缀表达式转前缀表达式(结果以空格隔开)infixToPrefixExpression: function(expression) {expression = Bee.StringUtils.deleteWhitespace(expression);expression = this.eliminatePositiveOrNegativeSign(expression);var operatorStack = [];var resultStack = [];var elementArr = expression.match(/[-+\/÷*×()]|(?:[1-9]\d*|0)(?:\.\d+)?/g);var size = elementArr.length;for(var i = size - 1; i >= 0; i--) {if(Bee.StringUtils.isNumeric(elementArr[i])) {//如果是数值resultStack.push(elementArr[i]);} else {//操作符栈顶元素var operatorStackTopElement = operatorStack.length === 0 ? '' : operatorStack[operatorStack.length - 1];//运算符if(operatorStack.length === 0 || elementArr[i] === ')' || operatorStackTopElement === ')' || this.operatorPrecedence[elementArr[i]] >= this.operatorPrecedence[operatorStackTopElement]) {//操作符栈为空或栈顶元素为右括号')',或操作符的优先级比栈顶运算符高或相等,直接入栈operatorStack.push(elementArr[i]);} else {//如果是左括号"(",则依次弹出操作符栈顶的运算符,并压入结果栈,直到遇到右括号')'为止,左右括号不压入结果栈;if(elementArr[i] === '(') {for(var index = operatorStack.length - 1; index >= 0; index--) {if(operatorStack[index] === ')') {operatorStack.pop();break;} else {resultStack.push(operatorStack.pop());}}} else {//将符号栈顶的运算符弹出并压入到结果栈中,再次与符号栈中新的栈顶运算符相比较resultStack.push(operatorStack.pop());i++;continue;}}}}//处理操作符栈剩余的符号if(operatorStack.length > 0) {for(var j = operatorStack.length - 1; j >= 0; j--) {resultStack.push(operatorStack.pop());}}//结果返回return resultStack.reverse().join(' ');},//解决正负号问题-1转为0-1;+1转为0+1eliminatePositiveOrNegativeSign: function(expression) {return expression.replace(/(\(|^)([-+])/g, '$10$2');},//把中缀表达式转为前缀表达式,再计算calculateByPrefixExpression: function(expression) {var elementArr = this.infixToPrefixExpression(expression).split(' ');var size = elementArr.length;var resultStack = [];for(var i = size - 1; i >= 0; i--) {if(Bee.StringUtils.isNumeric(elementArr[i])) {//如果是数值resultStack.push(elementArr[i]);} else {var operand1 = resultStack.pop();var operand2 = resultStack.pop();var result;switch(elementArr[i]) {case '+':result = Bee.ElementaryArithmeticUtils.add(operand1, operand2);break;case '-':result = Bee.ElementaryArithmeticUtils.subtract(operand1, operand2);break;case '×':case '*':result = Bee.ElementaryArithmeticUtils.multiply(operand1, operand2);break;case '\/':case '÷':result = Bee.ElementaryArithmeticUtils.divide(operand1, operand2);break;default:result = '';alert("The operator 【" + elementArr[i] + "】 is not legal");break;}resultStack.push(result);}}return resultStack;},//把中缀表达式转为后缀表达式,再计算calculateByPostfixExpression: function(expression) {var elementArr = this.infixToPostfixExpression(expression).split(' ');var size = elementArr.length;var resultStack = [];for(var i = 0; i < size; i++) {if(Bee.StringUtils.isNumeric(elementArr[i])) {//如果是数值resultStack.push(elementArr[i]);} else {var operand1 = resultStack.pop();var operand2 = resultStack.pop();var result;switch(elementArr[i]) {case '+':result = Bee.ElementaryArithmeticUtils.add(operand2, operand1);break;case '-':result = Bee.ElementaryArithmeticUtils.subtract(operand2, operand1);break;case '×':case '*':result = Bee.ElementaryArithmeticUtils.multiply(operand2, operand1);break;case '\/':case '÷':result = Bee.ElementaryArithmeticUtils.divide(operand2, operand1);break;default:result = '';alert("The operator 【" + elementArr[i] + "】 is not legal");break;}resultStack.push(result);}}return resultStack;},//横式计算horizontalCalculation: function(expression) {expression = Bee.StringUtils.deleteWhitespace(expression);expression = this.eliminatePositiveOrNegativeSign(expression);var result = expression;while(expression.indexOf('(') >= 0) {expression = expression.replace(/\([^()]+\)/g, function(matchStr) {return eval(matchStr);});result += '=' + expression;}while(expression.indexOf('[') >= 0) {expression = expression.replace(/\[[^\[\]]+\]/g, function(matchStr) {return eval(matchStr);});result += '=' + expression;}while(expression.indexOf('{') >= 0) {expression = expression.replace(/\{[^{}]+\}/g, function(matchStr) {return eval(matchStr);});result += '=' + expression;}var pattern = /(?:[1-9]\d*|0)(?:\.\d+)?[*/](?:[1-9]\d*|0)(?:\.\d+)?/;while(expression.indexOf('*') >= 0 || expression.indexOf('/') >= 0) {expression = expression.replace(pattern, function(matchStr, index) {return eval(matchStr);});result += '=' + expression;}if(/[-+*/]/.test(expression)) {result += '=' + eval(expression);}return result;},//竖式计算verticalCalculation: function(expression) {var result = this.horizontalCalculation(expression);return result.replace(/=/g, "\n$&");}};