先废话几句:AS中的浮点数计算误差也真是很有趣,例如:6.4-6.3=0.100000000000001,这是在Flash 8中运行的结果,附图一张:
evalString 函数介绍:
evalString(expression:String) : Number
expression 为一个算术表达式,该函数将计算此表达式的值,并返回计算结果。此表达式仅限于简单的+、-、×、÷以及带括号的运算,表达式中不得有其他符号,包括空格。表达式中的数字不仅限于一位整数,也可为多位整数,甚至是小数。
参数
expression:String – 一个字符串表达式。
返回
Number – 一个数值。
示例
var infix:String = “(48-20*(6.2-5))/(18-15)”;
trace(evalString(infix)); //output 8
函数算法思想
算法思想和上一篇《把中缀表达式转化为后缀表达式》中所表述的思想基本一致,只是在扫描数据以及运算符退栈时处理方法不同。
在扫描字符串时,若是数字,则加到一个字符串后面,同时扫描下一个字符,若不是数字字符也不是小数点,则把当前字符串转换为数字压入数字栈。
在遇到运算符需要退栈时,从数字栈中取出栈顶的两个数字,和退栈运算符一起进行运算,并把计算结果压入数字栈中,依次循环,直到无须退栈。扫描完成后,退栈运算符,并依次和数字栈中栈顶的数字进行运算,直至运算符栈为空。
函数代码如下:
/********************************************/ /* Calculate the value of a string */ /* Example: */ /* var infix:String = "(12.2-6.2)/(8-5)"; */ /* trace(evalString(infix)); //output 2 */ /********************************************/ /* Please keep this info when you quote */ /* www.afdream.com */ /* Author:Fdream */ /* Fdream All Rights Reserved */ /********************************************/ function evalString(infix:String) { var opArray:Array = new Array(); //栈底标记 opArray[0] = '@'; var op:Number = 1; var postfix:Array = new Array(); var post:Number = 0; //保存计算结果 var res:Number = 0; var i, j; var tempString:String = new String(); //计算两个数 function Caculate(opSign:String) { if (opSign == '+') { res = postfix[post-2]+postfix[post-1]; } else if (opSign == '-') { res = postfix[post-2]-postfix[post-1]; } else if (opSign == '*') { res = postfix[post-2]*postfix[post-1]; } else if (opSign == '/') { if (!postfix[post-1]) { trace("Expression Error!"); } else { res = postfix[post-2]/postfix[post-1]; } } postfix[post-1] = 0; postfix[post-2] = res; post--; } //扫描中缀表达式 for (i=0; i<infix.length; i++)="" {<br=""> switch (infix.charAt(i)) { //左括号就直接入栈 case '(' : opArray[op] = infix.charAt(i); op++; break; //右括号则退栈计算,直到遇见一个左括号 case ')' : for (j=op-1; j>0; j--) { if (opArray[j] != '(') { Caculate(opArray[j]); opArray[j] = '#'; } else { opArray[j] = '#'; break; } } op = j; break; case '*' : case '/' : //如果栈顶的运算符为*或/,则先退栈,再入栈,否则直接入栈 if (opArray[op-1] == '*') { op--; Caculate(opArray[op]); opArray[op] = '#'; } else if (opArray[op-1] == '/') { op--; Caculate(opArray[op]); opArray[op] = '#'; } opArray[op] = infix.charAt(i); op++; break; case '+' : case '-' : //如果栈顶的运算符不是左括号也不是栈底,则先退栈计算,再入栈 if (opArray[op-1] != '(' && opArray[op-1] != '@') { op--; Caculate(opArray[op]); opArray[op] = '#'; } opArray[op] = infix.charAt(i); op++; break; default : //如果是数字字符或者小数点则转化为数字存入数组 //如果下一个字符是运算符则把当前数字存入数组 tempString += infix.charAt(i); var temp:String = new String(); temp = infix.charAt(i+1); if (temp != '.' && (temp>'9' || temp<'0')) { postfix[post] = parseFloat(tempString); post++; tempString = ""; } //trace(postfix); } }</infix.length;> //扫描完成,全部退栈 for (j=op-1; j>0; j--) { if (opArray[j] != '@') { Caculate(opArray[j]); opArray[j] = '#'; } else { break; } } //返回结果 return postfix[0]; }
眼睛都看花咯还是看不懂
回去研究一哈.[smile][smile]
没必要看懂啦,直接拿去用就好了,嘿嘿
那个是计算机的浮点数运算的问题吧
2进制表示10进制会有误差的噢
不修正就会这样的
我认为可以把大家经常用到的Math也给解释了,比如Math就不输入了,直接”sqrt(2)”就是对2开方 这样能支持更多运算