最近使用PHP开发工资管理系统的过程中因为要进行工资计算,需要进行四则运算。查资料后,确定使用PHP的PEAR库的Math_Rpn类进行。然而在使用的过程中发现了该类库的
Bug。
1、问题描述
测试代码:
include('RPN.php'); $expArr=array( "(255.3*2)+33.2", "(655*2)+32.2", "(153*2)+31.2" ); $rpn = new Math_Rpn(); foreach($expArr as $val){ echo "$val=".$rpn->calculate($val,false)."<br />"; }
运行结果:
(255.3*2)+33.2=543.8 (655*2)+32.2=Syntax error (153*2)+31.2=Syntax error
2、bug原因
经过分析发现,出现此问题的原因在于该类并无构造方法来初始化变量的值,这样对于中缀表达式的计算时,上一次解析的值变成下一次解析运算中的脏数据。
3、解决方法
/** * Calculate the $input expression * * @param mixed $input Infix expression string or RPN expression string 中缀表达式或逆波兰式 * @param string $angle Angle's unit - 'rad' or 'deg' 角的单位 rad表弧度,deg表示度 * @param boolean $is_rpn True if $input is RPN expression or false if $input is infix expression * @return mixed Value of $input expression or a PEAR error * @access public */ function calculate($input = '',$is_rpn = true,$angle = 'rad') { $this->_angle = (boolean) ($angle == 'rad'); if($input == '') { $this->_error = $this->_raiseError('Empty input expression'); return $this->_error; } if(!$is_rpn) { /** * 多次连续调用计算中缀表达式时,因为未清除堆栈,上次的表达式数据成为脏数据,带入下次运算, * 造成表达式解析等出错! * 对input_array 和output进行初始化 * @author kelite * 2013-02-24 */ $this->_input_array=array(); $this->_output=array(); $this->_input = $input; $this->_stringToArray (); if($this->_error <> null) return $this->_error; $this->_arrayToRpn(); if($this->_error <> null) return $this->_error; } else { if (is_array($input)) { $input = implode(' ', $input); } $this->_input = $input; $this->_input_array = explode(' ',$input); $this->_output = explode(' ',$input); } $this->_rpnToValue(); if($this->_error <> null) return $this->_error; return $this->_value; }