[ Index ]

PHP Cross Reference of Web Application Component Toolkit

title

Body

[close]

/framework/template/components/data/ -> math_filter.inc.php (source)

   1  <?php
   2  //--------------------------------------------------------------------------------
   3  // Copyright 2004 Procata, Inc.
   4  // Released under the LGPL license (http://www.gnu.org/copyleft/lesser.html)
   5  //--------------------------------------------------------------------------------
   6  /**
   7  * @package WACT_FILTER
   8  * @author    Jason E. Sweat < jsweat_php AT yahoo DOT com >
   9  * @version $Id: math_filter.inc.php,v 1.2 2004/06/14 06:04:49 jsweat Exp $
  10  */
  11  //require_once 'Math/RPN.php';
  12  
  13  function math_filter($value, $exp, $file, $line) {
  14      $rpn =& new Math_Rpn();
  15      $rpn->Filter = 'math';
  16      $rpn->SourceFile = $file;
  17      $rpn->StartingLineNo = $line;
  18      //fix a quirk where RPN does not interpret - as subtraction
  19      //this only fixes it if it is the first operation of the expression
  20      if ('-' == substr($exp,0,1)) {
  21          $exp = '+-1*'.substr($exp,1);
  22      }
  23      $calc = '('.$value.')'.$exp;
  24      return $rpn->calculate($calc, 'deg', false);
  25  }
  26  
  27  /**
  28   * Math::Rpn
  29   *
  30   * Purpose:
  31   *
  32   *     Change Expression To RPN (Reverse Polish Notation), Calculate RPN Expression
  33   *
  34   * Example:
  35   *
  36   *     $expression = "(2^3)+sin(30)-(!4)+(3/4)";
  37   *
  38   *     $rpn = new RpnConverter(false);
  39   *     echo $rpn->getValue($expression);
  40   *
  41   * Example page:
  42   *
  43   *       http://www.maciek.maribex.wizja.net.pl/rpn/
  44   *
  45   * 2004-06-11 Jason E. Sweat < jsweat_php AT yahoo DOT com >
  46   * Modifications for use by WACT:
  47   * 1) elimination of PEAR.php include requirement
  48   *         this was done buy switching the _raiseError method
  49   *         to trigger a WACT error instead
  50   * 2) in several location, undefined indexes were referenced
  51   *         this was handled using the error suppression operator
  52   * 3) corrected error when parsing invalid expressions
  53   *
  54   * @author   Maciej Szczytowski <admin@e-rower.pl>
  55   * @version  1.1
  56   * @package  math
  57   * @access   public
  58   */
  59  class Math_Rpn
  60  {
  61      /**#@+
  62       * added for WACT error handling
  63       * @access protected
  64       */
  65      var $Filter;
  66      var $SourceFile;
  67      var $StartingLineNo;
  68      /**#@-*/
  69      /**
  70       * Input expression
  71       *
  72       * @var    string
  73       * @access private
  74       */
  75      var $_input = '';
  76  
  77      /**
  78       * Array with input expression
  79       *
  80       * @var    array
  81       * @access private
  82       */
  83      var $_input_array = array();
  84  
  85      /**
  86       * Array with output expression in RPN
  87       *
  88       * @var    array
  89       * @access private
  90       */
  91      var $_output = array();
  92  
  93      /**
  94       * Temporary stack
  95       *
  96       * @var    array
  97       * @access private
  98       */
  99      var $_stack = array();
 100  
 101      /**
 102       * Value of expression
 103       *
 104       * @var    float
 105       * @access private
 106       */
 107      var $_value = 0.0;
 108  
 109      /**
 110       * Angle's unit: rad - true, deg - false
 111       *
 112       * @var    boolean
 113       * @access private
 114       */
 115      var $_angle = true;
 116  
 117      /**
 118       * PEAR Error
 119       *
 120       * @var    object PEAR
 121       * @access private
 122       */
 123      var $_error = null;
 124  
 125      /**
 126       * Timer
 127       *
 128       * @var    float
 129       * @access private
 130       */
 131      var $_timer = 0.0;
 132  
 133      /**
 134       * Array of operators whit priority and math function
 135       * operator => (name, priority, number of arguments, function)
 136       *
 137       * @var    array
 138       * @access private
 139       */
 140      var $_operation = array (
 141          '('    => array ('left bracket', 0),
 142          ')'    => array ('right bracket', 1),
 143          '+'    => array ('sum', 1, 2, '_sum'),
 144          '-'    => array ('difference', 1, 2, '_difference'),
 145          '*'    => array ('multiplication', 2, 2, '_multiplication'),
 146          '/'    => array ('division', 2, 2, '_division'),
 147          'r'    => array ('root', 3, 2, '_root'),
 148          '^'    => array ('power', 3, 2, '_power'),
 149          'sin'  => array ('sine', 3, 1, '_sin'),
 150          'cos'  => array ('cosine', 3, 1, '_cos'),
 151          'tan'  => array ('tangent', 3, 1, '_tan'),
 152          'asin' => array ('asine', 3, 1, '_asin'),
 153          'acos' => array ('acosine', 3, 1, '_acos'),
 154          'atan' => array ('atangent', 3, 1, '_atan'),
 155          'sqrt' => array ('square root', 3, 1, '_sqrt'),
 156          'exp'    => array ('power of e', 3, 1, '_exp'),
 157          'log'  => array ('logarithm', 3, 1, '_log'),
 158          'ln'   => array ('natural logarithm', 3, 1, '_ln'),
 159          'E'  => array ('power of 10', 3, 1, '_E'),
 160          'abs'  => array ('absolute value', 3, 1, '_abs'),
 161          '!'    => array ('factorial', 3, 1, '_factorial'),
 162          'pi'   => array ('value of pi', 3, 0, '_const_pi'),
 163          'e'    => array ('value of e', 3, 0, '_const_e'),
 164          'mod'    => array ('modulo', 3, 2, '_mod'),
 165          'div'    => array ('integer division', 3, 2, '_div'),
 166      );
 167  
 168      /**
 169       * Return a WACT error
 170       *
 171       * @return object WACT error
 172       * @access private
 173       */
 174      function _raiseError ($error) {
 175          RaiseError('compiler', 'INTERNAL_FILTER_ERROR', array(
 176              'error' => $error,
 177              'filter' => $this->Filter,
 178              'file' => $this->SourceFile,
 179              'line' => $this->StartingLineNo));
 180      }
 181  
 182      /**
 183       * Return a operator's array
 184       *
 185       * @return array Array with operator's name, priority, arguments, function's name and syntax
 186       * @access public
 187       */
 188      function getOperators () {
 189          $return = array();
 190          while(list($key, $val) = each($this->_operation)) {
 191  
 192              if ($val[2] == 2) {
 193                  $syntax = 'A ' . $key . ' B';
 194              } elseif ($val[2] == 1) {
 195                  $syntax = $key . ' A';
 196              } else {
 197                  $syntax = $key;
 198              }
 199  
 200              $return[] = array (
 201                  'operator' => $key,
 202                  'name' => $val[0],
 203                  'priority' => $val[1],
 204                  'arguments' => $val[2],
 205                  'function' => $val[3],
 206                  'syntax' => $syntax
 207              );
 208          }
 209  
 210          return $return;
 211      }
 212  
 213      /**
 214       * Add new operator
 215       *
 216       * @param string $operator New operator
 217       * @param string $function Function name
 218       * @param integer $priority New operator's priority
 219       * @param integer $no_of_arg Number of function's arguments
 220       * @param string $text New operator's description
 221       * @access public
 222       */
 223      function addOperator ($operator, $function_name, $priority = 3, $no_of_arg = 0, $text = '') {
 224          if(preg_match("/^([\W\w]+)\:\:([\W\w]+)$/",$function_name,$match)) {
 225              $class = $match[1];
 226              $method = $match[2];
 227              $function = array (
 228                 'type' => 'userMethod',
 229                 'class' => $class,
 230                 'method' => $method
 231              );
 232          } else {
 233              $function = array (
 234                 'type' => 'userFunction',
 235                 'function' => $function_name
 236              );
 237          }
 238  
 239          $this->_operation[$operator] = array ($text, $priority, $no_of_arg, $function);
 240      }
 241  
 242      /**
 243       * Calculate the $input expression
 244       *
 245       * @param mixed $input Infix expression string or RPN expression array
 246       * @param string $angle Angle's unit - 'rad' or 'deg'
 247       * @param boolean $is_rpn True if $input is RPN expression or false if $input is infix expression
 248       * @return mixed Value of $input expression or a PEAR error
 249       * @access public
 250       */
 251      function calculate($input = '', $angle = 'rad', $is_rpn = false) {
 252          if($angle = 'deg') $this->_angle = false;
 253          else $this->_angle = true;
 254  
 255          if($input == '') {
 256              $this->_error = $this->_raiseError('Empty input expression');
 257              return $this->_error;
 258          }
 259  
 260          if(!$is_rpn) {
 261              $this->_input = $input;
 262  
 263              $this->_stringToArray ();
 264              if($this->_error <> null) return $this->_error;
 265  
 266              $this->_arrayToRpn();
 267              if($this->_error <> null) return $this->_error;
 268          } else {
 269              if(!is_array($input)) {
 270                  $this->_error = $this->_raiseError('Wrong input expression');
 271                  return $this->_error;
 272              }
 273              $this->_input = implode(' ',$input);
 274              $this->_input_array = $input;
 275              $this->_output = $input;
 276          }
 277  
 278          $this->_rpnToValue();
 279          if($this->_error <> null) return $this->_error;
 280  
 281          return $this->_value;
 282      }
 283  
 284      /**
 285       * Return a input array
 286       *
 287       * @return array Input array
 288       * @access public
 289       */
 290      function getInputArray() {
 291          return $this->_input_array;
 292      }
 293  
 294      /**
 295       * Return a RPN array
 296       *
 297       * @return array RPN array
 298       * @access public
 299       */
 300      function getRpnArray() {
 301          return $this->_output;
 302      }
 303  
 304      /**
 305       * Return a counting time in second
 306       *
 307       * @return float Counting time in seconds
 308       * @access public
 309       */
 310      function getTimer() {
 311          return $this->_timer;
 312      }
 313  
 314      /**
 315       * Check that $key is a key of $array (conformity to php<4.1.0)
 316       *
 317       * @param string $key
 318       * @param array $array
 319       * @param integer $type 0 - return true if $key is $array's key, 1 - return true if $key is $array's key and there isn't any occurrence of $key in another $array's key
 320       * @return boolean true when $key is a key of $array, or false
 321       * @access private
 322       */
 323  
 324      function _keyExists($key,$array,$type) {
 325          $keys = array_keys($array);
 326  
 327          if($type == 1) {
 328              $count = 0;
 329              while (list($keys_key, $keys_val) = each($keys)) {
 330                  if(is_integer(strpos($keys_val, $key)) && (strpos($keys_val, $key)==0)) $count++;
 331              }
 332              if(($count==1) && in_array($key,$keys)) return true;
 333              else return false;
 334          } else {
 335              if(in_array($key,$keys)) return true;
 336              else return false;
 337          }
 338      }
 339  
 340      /**
 341       * Check that $value is nan (conformity to php<4.2.0)
 342       *
 343       * @param float $value checking value
 344       * @return boolean true when $value is nan, or false
 345       * @access private
 346       */
 347      function _isNan($value) {
 348          if(function_exists('is_nan')) {
 349              return is_nan($value);
 350          } else {
 351              if((substr($value,-3) == 'IND') || (substr($value,-3) == 'NAN')) return true;
 352              else return false;
 353          }
 354      }
 355  
 356      /**
 357       * Check that $value is infinite (conformity to php<4.2.0)
 358       *
 359       * @param float $value checking value
 360       * @return boolean true when $value is infinite, or false
 361       * @access private
 362       */
 363      function _isInfinite($value) {
 364          if(function_exists('is_finite')) {
 365              return !is_finite($value);
 366          } else {
 367              if(substr($value,-3) == 'INF') return true;
 368              else return false;
 369          }
 370      }
 371  
 372      /**
 373       * Change input expression into array
 374       *
 375       * @return array Input expression changed into array
 376       * @access private
 377       */
 378      function _stringToArray () {
 379          $temp_operator = null;
 380          $temp_value = null;
 381  
 382          for($i = 0; $i < strlen($this->_input); $i++) {
 383              if ($this->_input[$i] == ' ') {
 384                  if ($temp_operator != null) {
 385                      array_push($this->_input_array, $temp_operator);
 386                      $temp_operator = null;
 387                  }
 388                  if ($temp_value != null) {
 389                      array_push($this->_input_array, $temp_value);
 390                      $temp_value = null;
 391                  }
 392              } elseif (
 393                  ($temp_value == null) 
 394                  && (@$this->_operation[$temp_operator][2]>0 
 395                      || !@isset($this->_operation[$temp_operator][2])) 
 396                  && ($this->_input[$i] == '-')
 397              ) {
 398                  if ($temp_operator != null) {
 399                      array_push($this->_input_array, $temp_operator);
 400                      $temp_operator = null;
 401                  }
 402  
 403                  array_push($this->_input_array, '-1');
 404                  array_push($this->_input_array, '*');
 405              } elseif ((is_numeric($this->_input[$i])) || ($this->_input[$i] == '.')) {
 406                  if ($temp_operator != null) {
 407                      array_push($this->_input_array, $temp_operator);
 408                      $temp_operator = null;
 409                  }
 410  
 411                  $temp_value .= $this->_input[$i];
 412              } else {
 413                  if ($this->_keyExists($temp_operator, $this->_operation, 1)) {
 414                      array_push($this->_input_array, $temp_operator);
 415                      $temp_operator = null;
 416                  }
 417  
 418                  if ($temp_value != null) {
 419                      array_push($this->_input_array, $temp_value);
 420                      $temp_value = null;
 421                  }
 422  
 423                  $temp_operator .= $this->_input[$i];
 424              }
 425          }
 426  
 427          if ($temp_operator != null) {
 428              array_push($this->_input_array, $temp_operator);
 429          } else {
 430              array_push($this->_input_array, $temp_value);
 431          }
 432  
 433          $this->_testInput();
 434  
 435          return $this->_input_array;
 436      }
 437  
 438      /**
 439       * Check input array and return correct array or a PEAR Error
 440       *
 441       * @return object Null or a PEAR Error
 442       * @access private
 443       */
 444      function _testInput() {
 445          if (!count($this->_input_array)) {
 446              $this->_input_array = null;
 447              $this->_error = $this->_raiseError('Undefined input array');
 448              return $this->_error;
 449          }
 450  
 451          $bracket = 0;
 452          for($i = 0; $i <= count($this->_input_array); $i++) if (@$this->_input_array[$i] == '(') $bracket++;
 453          for($i = 0; $i <= count($this->_input_array); $i++) if (@$this->_input_array[$i] == ')') $bracket--;
 454  
 455          if ($bracket <> 0) {
 456                  $this->_input_array = null;
 457                  $this->_error = $this->_raiseError('Syntax error');
 458                  return $this->_error;
 459          }
 460  
 461          for($i = 0; $i < count($this->_input_array); $i++) {
 462              if ((!is_numeric($this->_input_array[$i])) && (!$this->_keyExists($this->_input_array[$i], $this->_operation, 0))) {
 463                  $error_operator = $this->_input_array[$i];
 464                  $this->_input_array = null;
 465                  $this->_error = $this->_raiseError('Undefined operator \''. $error_operator.'\'');
 466                  return $this->_error;
 467              }
 468          }
 469  
 470          $this->_error = null;
 471          return $this->_error;
 472      }
 473  
 474      /**
 475       * Add value to the end of stack
 476       *
 477       * @param string $value Value to add into stack
 478       * @access private
 479       */
 480      function _stackAdd($value) {
 481          array_push($this->_stack, $value);
 482      }
 483  
 484      /**
 485       * Delete and return value from the end of stack
 486       *
 487       * @return string Value deleted from stack
 488       * @access private
 489       */
 490      function _stackDelete() {
 491          return array_pop($this->_stack);
 492      }
 493  
 494      /**
 495       * Return priority of value
 496       *
 497       * @param string $value Value to get priority
 498       * @return integer Priority
 499       * @access private
 500       */
 501      function _priority($value) {
 502          return $this->_operation[$value][1];
 503      }
 504      /**
 505       * Return priority of value from the end of stack
 506       *
 507       * @return integer Priority of operator from stack's top
 508       * @access private
 509       */
 510      function _stackPriority() {
 511          $value = $this->_stackDelete();
 512          $this->_stackAdd($value);
 513          return $this->_priority($value);
 514      }
 515  
 516      /**
 517       * Return true whene the stack is empty
 518       *
 519       * @return boolean Stack is empty (true) or not (false)
 520       * @access private
 521       */
 522      function _stackEmpty() {
 523          if (count($this->_stack)) {
 524              return false;
 525          }
 526          else return true;
 527      }
 528  
 529      /**
 530       * Add value into output array
 531       *
 532       * @param string $value Value to add into output array
 533       * @access private
 534       */
 535      function _outputAdd($value) {
 536          if ($value<>'(') {
 537              array_push($this->_output, $value);
 538          }
 539      }
 540  
 541      /**
 542       * Change input array into RPN array
 543       *
 544       * @return array Array with RPN expression
 545       * @access private
 546       */
 547      function _arrayToRpn() {
 548  
 549          if ($this->_error <> null) {
 550              $this->_output = array();
 551              return $this->_output;
 552          }
 553  
 554          for($i = 0; $i < count($this->_input_array); $i++) {
 555  
 556              $temp = $this->_input_array[$i];
 557  
 558              if (is_numeric($temp)) {
 559                  $this->_outputAdd($temp);
 560              } else {
 561                  if ($temp == ')') {
 562                      while(!$this->_stackEmpty() && ($this->_stackPriority() >= 1)) {
 563                          $this->_outputAdd($this->_stackDelete());
 564                      }
 565                      if (!$this->_stackEmpty()) {
 566                          $this->_stackDelete();
 567                      }
 568  
 569                  } elseif ($temp=='(') {
 570                      $this->_stackAdd($temp);
 571                  } elseif (($this->_stackEmpty()) || (($this->_priority($temp) > $this->_stackPriority()))) {
 572                     $this-> _stackAdd($temp);
 573                  } else {
 574                      while(!$this->_stackEmpty() && ($this->_priority($temp) <= $this->_stackPriority())) {
 575                          $this->_outputAdd($this->_stackDelete());
 576                      }
 577                      $this->_stackAdd($temp);
 578                  }
 579  
 580              }
 581  
 582          }
 583  
 584          while(!$this->_stackEmpty()) {
 585              $this->_outputAdd($this->_stackDelete());
 586          }
 587  
 588          return $this->_output;
 589      }
 590  
 591      /**
 592       * Return position of the first operator in array
 593       *
 594       * @param array $array Temporary array
 595       * @return integer Position of the first operator
 596       * @access private
 597       */
 598      function _nextOperator($array) {
 599          $pos = 0;
 600          while(is_numeric($array[$pos])) {
 601              $pos++;
 602              if ($pos >= count($array)) {
 603                  return -1;
 604              }
 605          }
 606          return $pos;
 607  
 608      }
 609  
 610      /**
 611       * Delete from array operator [posision $pos] and its argument and insert new value
 612       *
 613       * @param array $temp Temporary array
 614       * @param integer $pos Position of the last operator
 615       * @param integer $arg Number of last operator's arguments
 616       * @param float $result Last operation result
 617       * @return array New temporary array
 618       * @access private
 619       */
 620      function _refresh($temp, $pos, $arg, $result) {
 621          $temp1 = array_slice($temp, 0, $pos-$arg);
 622          $temp1[] = $result;
 623          $temp2 = array_slice($temp, $pos+1);
 624          return array_merge($temp1, $temp2);
 625      }
 626  
 627      /**
 628       * Math function
 629       *
 630       * @param array $temp Temporary array
 631       * @param integer $pos Position of operator
 632       * @return float Function's relult
 633       * @access private
 634       */
 635      function _sum($temp, $pos) {
 636          return $temp[$pos-2]+$temp[$pos-1];
 637      }
 638  
 639      /**
 640       * Math function
 641       *
 642       * @param array $temp Temporary array
 643       * @param integer $pos Position of operator
 644       * @return float Function's relult
 645       * @access private
 646       */
 647      function _difference($temp, $pos) {
 648          return $temp[$pos-2]-$temp[$pos-1];
 649      }
 650  
 651      /**
 652       * Math function
 653       *
 654       * @param array $temp Temporary array
 655       * @param integer $pos Position of operator
 656       * @return float Function's relult
 657       * @access private
 658       */
 659      function _multiplication($temp, $pos) {
 660          return $temp[$pos-2]*$temp[$pos-1];
 661      }
 662  
 663      /**
 664       * Math function
 665       *
 666       * @param array $temp Temporary array
 667       * @param integer $pos Position of operator
 668       * @return float Function's relult
 669       * @access private
 670       */
 671      function _division($temp, $pos) {
 672          if ($temp[$pos-1]==0) {
 673              $this->_error = $this->_raiseError('Division by 0');
 674              $this->_value = null;
 675              return $this->value;
 676          }
 677          return $temp[$pos-2]/$temp[$pos-1];
 678      }
 679  
 680      /**
 681       * Math function
 682       *
 683       * @param array $temp Temporary array
 684       * @param integer $pos Position of operator
 685       * @return float Function's relult
 686       * @access private
 687       */
 688      function _root($temp, $pos) {
 689          return pow($temp[$pos-1], (1/$temp[$pos-2]));
 690      }
 691  
 692      /**
 693       * Math function
 694       *
 695       * @param array $temp Temporary array
 696       * @param integer $pos Position of operator
 697       * @return float Function's relult
 698       * @access private
 699       */
 700      function _power($temp, $pos) {
 701          return pow($temp[$pos-2], $temp[$pos-1]);
 702      }
 703  
 704      /**
 705       * Math function
 706       *
 707       * @param array $temp Temporary array
 708       * @param integer $pos Position of operator
 709       * @return float Function's relult
 710       * @access private
 711       */
 712      function _sin($temp, $pos) {
 713          if ($this->_angle) {
 714              $angle = $temp[$pos-1];
 715          } else {
 716              $angle = deg2rad($temp[$pos-1]);
 717          }
 718          return sin($angle);
 719      }
 720  
 721      /**
 722       * Math function
 723       *
 724       * @param array $temp Temporary array
 725       * @param integer $pos Position of operator
 726       * @return float Function's relult
 727       * @access private
 728       */
 729      function _cos($temp, $pos) {
 730          if ($this->_angle) {
 731              $angle = $temp[$pos-1];
 732          } else {
 733              $angle = deg2rad($temp[$pos-1]);
 734          }
 735          return cos($angle);
 736      }
 737  
 738      /**
 739       * Math function
 740       *
 741       * @param array $temp Temporary array
 742       * @param integer $pos Position of operator
 743       * @return float Function's relult
 744       * @access private
 745       */
 746      function _tan($temp, $pos) {
 747          if ($this->_angle) {
 748              $angle = $temp[$pos-1];
 749          } else {
 750              $angle = deg2rad($temp[$pos-1]);
 751          }
 752          return tan($angle);
 753      }
 754  
 755      /**
 756       * Math function
 757       *
 758       * @param array $temp Temporary array
 759       * @param integer $pos Position of operator
 760       * @return float Function's relult
 761       * @access private
 762       */
 763      function _asin($temp, $pos) {
 764          $angle = asin($temp[$pos-1]);
 765          if (!$this->_angle) {
 766              $angle = rad2deg($angle);
 767          }
 768          return $angle;
 769      }
 770  
 771      /**
 772       * Math function
 773       *
 774       * @param array $temp Temporary array
 775       * @param integer $pos Position of operator
 776       * @return float Function's relult
 777       * @access private
 778       */
 779      function _acos($temp, $pos) {
 780          $angle = acos($temp[$pos-1]);
 781          if (!$this->_angle) {
 782              $angle = rad2deg($angle);
 783          }
 784          return $angle;
 785      }
 786  
 787      /**
 788       * Math function
 789       *
 790       * @param array $temp Temporary array
 791       * @param integer $pos Position of operator
 792       * @return float Function's relult
 793       * @access private
 794       */
 795      function _atan($temp, $pos) {
 796          $angle = atan($temp[$pos-1]);
 797          if (!$this->_angle) {
 798              $angle = rad2deg($angle);
 799          }
 800          return $angle;
 801      }
 802  
 803      /**
 804       * Math function
 805       *
 806       * @param array $temp Temporary array
 807       * @param integer $pos Position of operator
 808       * @return float Function's relult
 809       * @access private
 810       */
 811      function _sqrt($temp, $pos) {
 812          return sqrt($temp[$pos-1]);
 813      }
 814  
 815      /**
 816       * Math function
 817       *
 818       * @param array $temp Temporary array
 819       * @param integer $pos Position of operator
 820       * @return float Function's relult
 821       * @access private
 822       */
 823      function _exp($temp, $pos) {
 824          return exp($temp[$pos-1]);
 825      }
 826  
 827      /**
 828       * Math function
 829       *
 830       * @param array $temp Temporary array
 831       * @param integer $pos Position of operator
 832       * @return float Function's relult
 833       * @access private
 834       */
 835      function _log($temp, $pos) {
 836          return log10($temp[$pos-1]);
 837      }
 838  
 839      /**
 840       * Math function
 841       *
 842       * @param array $temp Temporary array
 843       * @param integer $pos Position of operator
 844       * @return float Function's relult
 845       * @access private
 846       */
 847      function _ln($temp, $pos) {
 848          return log($temp[$pos-1]);
 849      }
 850  
 851      /**
 852       * Math function
 853       *
 854       * @param array $temp Temporary array
 855       * @param integer $pos Position of operator
 856       * @return float Function's relult
 857       * @access private
 858       */
 859      function _const_pi($temp, $pos) {
 860          return M_PI;
 861      }
 862  
 863      /**
 864       * Math function
 865       *
 866       * @param array $temp Temporary array
 867       * @param integer $pos Position of operator
 868       * @return float Function's relult
 869       * @access private
 870       */
 871      function _const_e($temp, $pos) {
 872          return M_E;
 873      }
 874  
 875      /**
 876       * Math function
 877       *
 878       * @param array $temp Temporary array
 879       * @param integer $pos Position of operator
 880       * @return float Function's relult
 881       * @access private
 882       */
 883      function _E($temp, $pos) {
 884          return pow(10, $temp[$pos-1]);
 885      }
 886  
 887      /**
 888       * Math function
 889       *
 890       * @param array $temp Temporary array
 891       * @param integer $pos Position of operator
 892       * @return float Function's relult
 893       * @access private
 894       */
 895      function _factorial($temp, $pos) {
 896          $factorial = 1;
 897          for($i=1;$i<=$temp[$pos-1];$i++) {
 898              $factorial *= $i;
 899          }
 900          return $factorial;
 901      }
 902  
 903      /**
 904       * Math function
 905       *
 906       * @param array $temp Temporary array
 907       * @param integer $pos Position of operator
 908       * @return float Function's relult
 909       * @access private
 910       */
 911      function _abs($temp, $pos) {
 912          return abs($temp[$pos-1]);
 913      }
 914  
 915      /**
 916       * Math function
 917       *
 918       * @param array $temp Temporary array
 919       * @param integer $pos Position of operator
 920       * @return float Function's relult
 921       * @access private
 922       */
 923      function _mod($temp, $pos) {
 924          return $temp[$pos-2]%$temp[$pos-1];
 925      }
 926  
 927      /**
 928       * Math function
 929       *
 930       * @param array $temp Temporary array
 931       * @param integer $pos Position of operator
 932       * @return float Function's relult
 933       * @access private
 934       */
 935      function _div($temp, $pos) {
 936          return floor($temp[$pos-2]/$temp[$pos-1]);
 937      }
 938  
 939      /**
 940       * Calculate RPN Expression and return value
 941       *
 942       * @return float Result of input expression
 943       * @access private
 944       */
 945      function _rpnToValue() {
 946  
 947          $time1 = $this->_getMicroTime();
 948  
 949          if ($this->_error <> null) {
 950              $this->_value = null;
 951              return $this->_value;
 952          }
 953  
 954          $this->_value = 0;
 955          $temp = $this->_output;
 956  
 957          do {
 958              $pos = $this->_nextOperator($temp);
 959  
 960              if ($pos == -1) {
 961                  $this->_error = $this->_raiseError('Syntax error');
 962                  $this->_value = null;
 963                  return $this->_value;
 964              }
 965  
 966              $operator = $this->_operation[$temp[$pos]];
 967              $arg = $operator[2];
 968              $function = $operator[3];
 969  
 970              if (($arg==2) && ((!is_numeric($temp[$pos-1])) || (!is_numeric($temp[$pos-2])))) {
 971                  $this->_error = $this->_raiseError('Syntax error');
 972                  $this->_value = null;
 973                  return $this->_value;
 974              } elseif (($arg==1) && (!is_numeric($temp[$pos-1]))) {
 975                  $this->_error = $this->_raiseError('Syntax error');
 976                  $this->_value = null;
 977                  return $this->_value;
 978              }
 979  
 980              if(is_array($function)) {
 981  
 982                  if($arg==2) $arg_array = array($temp[$pos-2],$temp[$pos-1]);
 983                  elseif($arg==1) $arg_array = array($temp[$pos-1]);
 984                  else $arg_array = array();
 985  
 986                  if($function['type'] == 'userFunction') {
 987                      $this->_value = call_user_func_array($function['function'], $arg_array);
 988                  } else {
 989                      $function_array = array(&$function['class'], $function['method']);
 990                      $this->_value = call_user_func_array($function_array, $arg_array);
 991                  }
 992              } else {
 993                  if (method_exists($this, $function)) {
 994                      $this->_value = $this->$function($temp, $pos);
 995                  } else {
 996                      $this->_raiseError("invalid function '$function' temp '$temp' pos '$pos'");
 997                  }
 998              }
 999  
1000              if ($this->_isNan($this->_value)) {
1001                  $this->_error = $this->_raiseError('NAN value');
1002                  $this->_value = null;
1003                  return $this->_value;
1004              } elseif ($this->_isInfinite($this->_value)) {
1005                  $this->_error = $this->_raiseError('Infinite value');
1006                  $this->_value = null;
1007                  return $this->_value;
1008              } elseif (is_null($this->_value)) {
1009                  return $this->_value;
1010              }
1011  
1012              $temp = $this->_refresh($temp, $pos, $arg, $this->_value);
1013          } while(count($temp) > 1);
1014  
1015          $this->_value = $temp[0];
1016  
1017          $time2 = $this->_getMicroTime();
1018  
1019          $this->_timer = $time2 - $time1;
1020  
1021          return $this->_value;
1022      }
1023  
1024      /**
1025       * Return a time in second
1026       *
1027       * @return float Current time in seconds
1028       * @access private
1029       */
1030      function _getMicroTime() {
1031          list($usec, $sec) = explode(" ", microtime());
1032          return ((float)$usec + (float)$sec);
1033      }
1034  
1035  }
1036  
1037  ?>


Generated: Sun Nov 28 19:36:09 2004 Cross-referenced by PHPXref 0.5