diff --git a/sphinx_doc_src/cmds/math.rst b/sphinx_doc_src/cmds/math.rst index b5107ead5..93d5ea8e5 100644 --- a/sphinx_doc_src/cmds/math.rst +++ b/sphinx_doc_src/cmds/math.rst @@ -16,7 +16,7 @@ Description By default, the output is as a float with trailing zeroes trimmed. To get a fixed representation, the ``--scale`` option can be used, including ``--scale=0`` for integer output. -Keep in mind that parameter expansion takes before expressions are evaluated. This can be very useful in order to perform calculations involving shell variables or the output of command substitutions, but it also means that parenthesis (``()``) and the asterisk (``*``) glob character have to be escaped or quoted. +Keep in mind that parameter expansion takes before expressions are evaluated. This can be very useful in order to perform calculations involving shell variables or the output of command substitutions, but it also means that parenthesis (``()``) and the asterisk (``*``) glob character have to be escaped or quoted. ``x`` can also be used to denote multiplication, but it needs to be followed by whitespace to distinguish it from hexadecimal numbers. ``math`` ignores whitespace between arguments and takes its input as multiple arguments (internally joined with a space), so ``math 2 +2`` and ``math "2 + 2"`` work the same. ``math 2 2`` is an error. @@ -43,7 +43,7 @@ Operators - ``+`` for addition and ``-`` for subtraction. -- ``*`` for multiplication, ``/`` for division. (Note that ``*`` is the glob character and needs to be quoted or escaped.) +- ``*`` or ``x`` for multiplication, ``/`` for division. (Note that ``*`` is the glob character and needs to be quoted or escaped, ``x`` needs to be followed by whitespace or it looks like ``0x`` hexadecimal notation.) - ``^`` for exponentiation. @@ -110,6 +110,8 @@ Examples ``math 5 \* 2`` or ``math "5 * 2"`` or ``math 5 "*" 2`` all output ``10``. +``math 0xFF`` outputs 255, ``math 0 x 3`` outputs 0 (because it computes 0 multiplied by 3). + Compatibility notes ------------------- diff --git a/src/tinyexpr.cpp b/src/tinyexpr.cpp index c0a492c68..73ed61b77 100644 --- a/src/tinyexpr.cpp +++ b/src/tinyexpr.cpp @@ -233,7 +233,10 @@ void next_token(state *s) { s->type = TOK_NUMBER; } else { /* Look for a variable or builtin function call. */ - if (s->next[0] >= 'a' && s->next[0] <= 'z') { + // But not when it's an "x" followed by whitespace + // - that's the alternative multiplication operator. + if (s->next[0] >= 'a' && s->next[0] <= 'z' && + !(s->next[0] == 'x' && isspace(s->next[1]))) { const char *start; start = s->next; while ((s->next[0] >= 'a' && s->next[0] <= 'z') || @@ -269,7 +272,9 @@ void next_token(state *s) { s->type = TOK_INFIX; s->function = (const void *)(te_fun2)sub; break; + case 'x': case '*': + // We've already checked for whitespace above. s->type = TOK_INFIX; s->function = (const void *)(te_fun2)mul; break; diff --git a/tests/math.err b/tests/math.err index 6d4dcc1ca..dad9f7ca4 100644 --- a/tests/math.err +++ b/tests/math.err @@ -34,3 +34,9 @@ math: Error: Result is infinite '2^999999' math: Error: Result is infinite '1 / 0' + +#################### +# Validate x as multiplier +math: Error: Unknown variable +'2 x4' + ^ diff --git a/tests/math.in b/tests/math.in index 2c92ee052..9bcac3b93 100644 --- a/tests/math.in +++ b/tests/math.in @@ -52,3 +52,10 @@ not math not math -s 12 not math 2^999999 not math 1 / 0 + +logmsg Validate "x" as multiplier +math 0x2 # Hex +math 5 x 4 +math 2x 4 +math 2 x4 # ERROR +math 0x 3 diff --git a/tests/math.out b/tests/math.out index 05aadc40a..ffe7b8604 100644 --- a/tests/math.out +++ b/tests/math.out @@ -49,3 +49,10 @@ #################### # Validate math error reporting + +#################### +# Validate x as multiplier +2 +20 +8 +0