public function getRandomValue() { // @todo check this include_once "./Services/Math/classes/class.ilMath.php"; $mul = ilMath::_pow(10, $this->getPrecision()); $r1 = round(ilMath::_mul($this->getRangeMin(), $mul)); $r2 = round(ilMath::_mul($this->getRangeMax(), $mul)); $calcval = $this->getRangeMin() - 1; //test $roundedRangeMIN = round($this->getRangeMin(), $this->getPrecision()); $roundedRangeMAX = round($this->getRangeMax(), $this->getPrecision()); while ($calcval < $roundedRangeMIN || $calcval > $roundedRangeMAX) { $rnd = mt_rand($r1, $r2); $calcval = ilMath::_div($rnd, $mul, $this->getPrecision()); if ($this->getPrecision() == 0 && $this->getIntprecision() != 0) { if ($this->getIntprecision() > 0) { $modulo = $calcval % $this->getIntprecision(); if ($modulo != 0) { if ($modulo < ilMath::_div($this->getIntprecision(), 2)) { $calcval = ilMath::_sub($calcval, $modulo, $this->getPrecision()); } else { $calcval = ilMath::_add($calcval, ilMath::_sub($this->getIntprecision(), $modulo, $this->getPrecision()), $this->getPrecision()); } } } } } return $calcval; }
function pfx($tokens, $vars = array()) { if ($tokens == false) { return false; } $stack = new EvalMathStack(); foreach ($tokens as $token) { // nice and easy // if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on if (in_array($token, array('+', '-', '*', '/', '^'))) { if (is_null($op2 = $stack->pop())) { return $this->trigger("internal error"); } if (is_null($op1 = $stack->pop())) { return $this->trigger("internal error"); } include_once "class.ilMath.php"; switch ($token) { case '+': $stack->push(ilMath::_add($op1, $op2)); break; case '-': $stack->push(ilMath::_sub($op1, $op2)); break; case '*': $stack->push(ilMath::_mul($op1, $op2)); break; case '/': if ($op2 == 0) { return $this->trigger("division by zero"); } $stack->push(ilMath::_div($op1, $op2)); break; case '^': $stack->push(ilMath::_pow($op1, $op2)); break; } // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on } elseif ($token == "_") { $stack->push(-1 * $stack->pop()); // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on } elseif (preg_match("/^([a-z]\\w*)\\(\$/", $token, $matches)) { // it's a function! $fnn = $matches[1]; if (in_array($fnn, $this->fb)) { // built-in function: if (is_null($op1 = $stack->pop())) { return $this->trigger("internal error"); } $fnn = preg_replace("/^arc/", "a", $fnn); // for the 'arc' trig synonyms if ($fnn == 'ln') { $fnn = 'log'; } eval('$stack->push(' . $fnn . '($op1));'); // perfectly safe eval() } elseif (array_key_exists($fnn, $this->f)) { // user function // get args $args = array(); for ($i = count($this->f[$fnn]['args']) - 1; $i >= 0; $i--) { if (is_null($args[$this->f[$fnn]['args'][$i]] = $stack->pop())) { return $this->trigger("internal error"); } } $stack->push($this->pfx($this->f[$fnn]['func'], $args)); // yay... recursion!!!! } // if the token is a number or variable, push it on the stack } else { if (is_numeric($token)) { $stack->push($token); } elseif (($hex = $this->from_hexbin($token)) !== FALSE) { $stack->push($hex); } elseif (array_key_exists($token, $this->v)) { $stack->push($this->v[$token]); } elseif (array_key_exists($token, $vars)) { $stack->push($vars[$token]); } else { return $this->trigger("undefined variable '{$token}'"); } } } // when we're out of tokens, the stack should have a single element, the final result if ($stack->count != 1) { return $this->trigger("internal error"); } return $stack->pop(); }