zoukankan      html  css  js  c++  java
  • PHP pear库中的RPN类bug及修复

    最近使用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;
        }
    

      

      

      

      

  • 相关阅读:
    mangodb学习0.1 概念
    express 学习笔记(一)路由
    vue配置路由
    screenX, clientX, pageX
    svg的世界、视窗、视野
    window.print()打印网页(一)
    cookie基础
    BOM基础
    Java三大特征:封装 继承 多态
    面向对象
  • 原文地址:https://www.cnblogs.com/kelite/p/2923917.html
Copyright © 2011-2022 走看看