aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Denker <jsd@av8n.com>2021-11-11 16:02:59 -0700
committerJohn Denker <jsd@av8n.com>2021-11-11 16:08:19 -0700
commit0a4028e9f1170bda49fe6bc10b9b1be04441d8b2 (patch)
tree5b4e11861763c3f38748a801e3084aa02a1fe56e
parent458bfd01ce86279b71dee182c9ea9e63f9ed71f0 (diff)
implement floor(x), ceil(x), and modulo (x % y)
-rw-r--r--parser.php122
1 files changed, 92 insertions, 30 deletions
diff --git a/parser.php b/parser.php
index 80e01c2..cd7e6c2 100644
--- a/parser.php
+++ b/parser.php
@@ -858,6 +858,61 @@ class qtype_algebra_parser_divide extends qtype_algebra_parser_term {
);
}
+/**
+ * Class representing a modulo operation in an algebraic expression.
+ *
+ * The parser creates an instance of this term when it finds a string matching the modulo
+ * operator's syntax. The string which corresponds to the term is passed to the constructor
+ * of this subclass.
+ */
+class qtype_algebra_parser_modulo extends qtype_algebra_parser_term {
+
+ /**
+ * Constructs an instance of a modulo operator term.
+ *
+ * This function initializes an instance of a modulo operator term using the string which
+ * matches the modulo operator expression. Since this is simply the character representing
+ * the operator it is not used except when producing a string representation of the term.
+ *
+ * @param $text string matching the term's regular expression
+ */
+ public function __construct($text) {
+ parent::__construct(self::NARGS, self::$formats, $text);
+ }
+
+ /**
+ * Evaluates the modulo operation numerically.
+ *
+ * Overrides the base class method to simply return the numerical value of the modulo
+ * operation. The method evaluates the two arguments of the term and then performs
+ * the required operation to get the return value.
+ *
+ * @param $params array of values keyed by variable name
+ * @return the numerical value of the term given the provided values for the variables
+ */
+ public function evaluate($params) {
+ $this->check_arguments();
+ // Get the value we are trying to modulo by.
+ $denom = $this->_arguments[1]->evaluate($params);
+ // Check to see if this is zero.
+ if ($denom == 0) {
+ // Check the sign of the other argument and use to determine whether we return
+ // plus or minus infinity.
+ return INF * $this->_arguments[0]->evaluate($params);
+ } else {
+ $nume = $this->_arguments[0]->evaluate($params);
+ $rslt = fmod($nume, $denom);
+ return $rslt;
+ }
+ }
+
+ // Static class properties.
+ const NARGS = 2;
+ private static $formats = array(
+ 'str' => '%s%%%s',
+ 'tex' => '{%s}\%%{%s}'
+ );
+}
/**
* Class representing a multiplication operation in an algebraic expression.
@@ -1307,16 +1362,19 @@ class qtype_algebra_parser_function extends qtype_algebra_parser_term {
* functions are implemented without pseudonyms
*/
public static $fnmap = array ();
- public static $texmap = array('sqrt' => '\\sqrt',
- 'log2' => '\\log_{2}',
- 'log10' => '\\log_{10}',
- 'asin' => '\\sin^{-1}',
- 'acos' => '\\cos^{-1}',
- 'atan' => '\\tan^{-1}',
- 'asinh' => '\\sinh^{-1}',
- 'acosh' => '\\cosh^{-1}',
- 'atanh' => '\\tanh^{-1}',
- );
+ public static $texmap = array(
+ 'floor' => '\\mathrm{floor}',
+ 'ceil' => '\\mathrm{ceil}',
+ 'sqrt' => '\\sqrt',
+ 'log2' => '\\log_{2}',
+ 'log10' => '\\log_{10}',
+ 'asin' => '\\sin^{-1}',
+ 'acos' => '\\cos^{-1}',
+ 'atan' => '\\tan^{-1}',
+ 'asinh' => '\\sinh^{-1}',
+ 'acosh' => '\\cosh^{-1}',
+ 'atanh' => '\\tanh^{-1}',
+ );
// List of functions requiring special brackets.
public static $bracketmap = array ('sqrt'
@@ -1441,32 +1499,35 @@ class qtype_algebra_parser {
// Functions which the parser will understand.
// You have to implement any that are not standard PHP math functions.
- public static $functions = array ('sqrt',
- 'exp',
- 'log2',
- 'ln',
- 'log',
- 'log10',
- 'sinh',
- 'cosh',
- 'tanh',
- 'sin',
- 'cos',
- 'tan',
- 'asin',
- 'acos',
- 'atan',
- 'asinh',
- 'acosh',
- 'atanh',
- );
+ public static $functions = array (
+ 'floor',
+ 'ceil',
+ 'sqrt',
+ 'exp',
+ 'log2',
+ 'ln',
+ 'log',
+ 'log10',
+ 'sinh',
+ 'cosh',
+ 'tanh',
+ 'sin',
+ 'cos',
+ 'tan',
+ 'asin',
+ 'acos',
+ 'atan',
+ 'asinh',
+ 'acosh',
+ 'atanh',
+ );
// Array to define the priority of the different operations. The parser implements the standard BODMAS priority:
// brackets, order (power), division, mulitplication, addition, subtraction.
private static $priority = array (
array('qtype_algebra_parser_power'),
array('qtype_algebra_parser_function'),
- array('qtype_algebra_parser_divide', 'qtype_algebra_parser_multiply'),
+ array('qtype_algebra_parser_divide', 'qtype_algebra_parser_multiply', 'qtype_algebra_parser_modulo'),
array('qtype_algebra_parser_add', 'qtype_algebra_parser_subtract')
);
@@ -1493,6 +1554,7 @@ class qtype_algebra_parser {
$this->_tokens = array (
array ('/(\^|\*\*)/A', 'qtype_algebra_parser_power' )
, array ('/\//A', 'qtype_algebra_parser_divide' )
+ , array ('/%/A', 'qtype_algebra_parser_modulo' )
, array ('/\*/A', 'qtype_algebra_parser_multiply' )
, array ('/\+/A', 'qtype_algebra_parser_add' )
, array ('/-/A', 'qtype_algebra_parser_subtract' )