UNPKG

27.5 kBMarkdownView Raw
1# Expression syntax
2
3This page describes the syntax of expression parser of math.js. It describes
4how to work with the available data types, functions, operators, variables,
5and more.
6
7## Differences from JavaScript
8
9The expression parser of math.js is aimed at a mathematical audience,
10not a programming audience. The syntax is similar to most calculators and
11mathematical applications. This is close to JavaScript as well, though there
12are a few important differences between the syntax of the expression parser and
13the lower level syntax of math.js. Differences are:
14
15- No need to prefix functions and constants with the `math.*` namespace,
16 you can just enter `sin(pi / 4)`.
17- Matrix indexes are one-based instead of zero-based.
18- There are index and range operators which allow more conveniently getting
19 and setting matrix indexes, like `A[2:4, 1]`.
20- Both indexes and ranges and have the upper-bound included.
21- There is a differing syntax for defining functions. Example: `f(x) = x^2`.
22- There are custom operators like `x + y` instead of `add(x, y)`.
23- Some operators are different. For example `^` is used for exponentiation,
24 not bitwise xor.
25- Implicit multiplication, like `2 pi`, is supported and has special rules.
26- Relational operators (`<`, `>`, `<=`, `>=`, `==`, and `!=`) are chained, so the expression `5 < x < 10` is equivalent to `5 < x and x < 10`.
27
28
29## Operators
30
31The expression parser has operators for all common arithmetic operations such
32as addition and multiplication. The expression parser uses conventional infix
33notation for operators: an operator is placed between its arguments.
34Round parentheses can be used to override the default precedence of operators.
35
36```js
37// use operators
38math.evaluate('2 + 3') // 5
39math.evaluate('2 * 3') // 6
40
41// use parentheses to override the default precedence
42math.evaluate('2 + 3 * 4') // 14
43math.evaluate('(2 + 3) * 4') // 20
44```
45
46The following operators are available:
47
48Operator | Name | Syntax | Associativity | Example | Result
49----------- | ----------------------- | ---------- | ------------- | --------------------- | ---------------
50`(`, `)` | Grouping | `(x)` | None | `2 * (3 + 4)` | `14`
51`[`, `]` | Matrix, Index | `[...]` | None | `[[1,2],[3,4]]` | `[[1,2],[3,4]]`
52`{`, `}` | Object | `{...}` | None | `{a: 1, b: 2}` | `{a: 1, b: 2}`
53`,` | Parameter separator | `x, y` | Left to right | `max(2, 1, 5)` | `5`
54`.` | Property accessor | `obj.prop` | Left to right | `obj={a: 12}; obj.a` | `12`
55`;` | Statement separator | `x; y` | Left to right | `a=2; b=3; a*b` | `[6]`
56`;` | Row separator | `[x; y]` | Left to right | `[1,2;3,4]` | `[[1,2],[3,4]]`
57`\n` | Statement separator | `x \n y` | Left to right | `a=2 \n b=3 \n a*b` | `[2,3,6]`
58`+` | Add | `x + y` | Left to right | `4 + 5` | `9`
59`+` | Unary plus | `+y` | Right to left | `+4` | `4`
60`-` | Subtract | `x - y` | Left to right | `7 - 3` | `4`
61`-` | Unary minus | `-y` | Right to left | `-4` | `-4`
62`*` | Multiply | `x * y` | Left to right | `2 * 3` | `6`
63`.*` | Element-wise multiply | `x .* y` | Left to right | `[1,2,3] .* [1,2,3]` | `[1,4,9]`
64`/` | Divide | `x / y` | Left to right | `6 / 2` | `3`
65`./` | Element-wise divide | `x ./ y` | Left to right | `[9,6,4] ./ [3,2,2]` | `[3,3,2]`
66`%`, `mod` | Modulus | `x % y` | Left to right | `8 % 3` | `2`
67`^` | Power | `x ^ y` | Right to left | `2 ^ 3` | `8`
68`.^` | Element-wise power | `x .^ y` | Right to left | `[2,3] .^ [3,3]` | `[8,27]`
69`'` | Transpose | `y'` | Left to right | `[[1,2],[3,4]]'` | `[[1,3],[2,4]]`
70`!` | Factorial | `y!` | Left to right | `5!` | `120`
71`&` | Bitwise and | `x & y` | Left to right | `5 & 3` | `1`
72`~` | Bitwise not | `~x` | Right to left | `~2` | `-3`
73<code>&#124;</code> | Bitwise or | <code>x &#124; y</code> | Left to right | <code>5 &#124; 3</code> | `7`
74<code>^&#124;</code> | Bitwise xor | <code>x ^&#124; y</code> | Left to right | <code>5 ^&#124; 2</code> | `7`
75`<<` | Left shift | `x << y` | Left to right | `4 << 1` | `8`
76`>>` | Right arithmetic shift | `x >> y` | Left to right | `8 >> 1` | `4`
77`>>>` | Right logical shift | `x >>> y` | Left to right | `-8 >>> 1` | `2147483644`
78`and` | Logical and | `x and y` | Left to right | `true and false` | `false`
79`not` | Logical not | `not y` | Right to left | `not true` | `false`
80`or` | Logical or | `x or y` | Left to right | `true or false` | `true`
81`xor` | Logical xor | `x xor y` | Left to right | `true xor true` | `false`
82`=` | Assignment | `x = y` | Right to left | `a = 5` | `5`
83`?` `:` | Conditional expression | `x ? y : z` | Right to left | `15 > 100 ? 1 : -1` | `-1`
84`:` | Range | `x : y` | Right to left | `1:4` | `[1,2,3,4]`
85`to`, `in` | Unit conversion | `x to y` | Left to right | `2 inch to cm` | `5.08 cm`
86`==` | Equal | `x == y` | Left to right | `2 == 4 - 2` | `true`
87`!=` | Unequal | `x != y` | Left to right | `2 != 3` | `true`
88`<` | Smaller | `x < y` | Left to right | `2 < 3` | `true`
89`>` | Larger | `x > y` | Left to right | `2 > 3` | `false`
90`<=` | Smallereq | `x <= y` | Left to right | `4 <= 3` | `false`
91`>=` | Largereq | `x >= y` | Left to right | `2 + 4 >= 6` | `true`
92
93
94## Precedence
95
96The operators have the following precedence, from highest to lowest:
97
98Operators | Description
99--------------------------------- | --------------------
100`(...)`<br>`[...]`<br>`{...}` | Grouping<br>Matrix<br>Object
101`x(...)`<br>`x[...]`<br>`obj.prop`<br>`:`| Function call<br>Matrix index<br>Property accessor<br>Key/value separator
102`'` | Matrix transpose
103`!` | Factorial
104`^`, `.^` | Exponentiation
105`+`, `-`, `~`, `not` | Unary plus, unary minus, bitwise not, logical not
106See section below | Implicit multiplication
107`*`, `/`, `.*`, `./`, `%`, `mod` | Multiply, divide, modulus
108`+`, `-` | Add, subtract
109`:` | Range
110`to`, `in` | Unit conversion
111`<<`, `>>`, `>>>` | Bitwise left shift, bitwise right arithmetic shift, bitwise right logical shift
112`==`, `!=`, `<`, `>`, `<=`, `>=` | Relational
113`&` | Bitwise and
114<code>^&#124;</code> | Bitwise xor
115<code>&#124;</code> | Bitwise or
116`and` | Logical and
117`xor` | Logical xor
118`or` | Logical or
119`?`, `:` | Conditional expression
120`=` | Assignment
121`,` | Parameter and column separator
122`;` | Row separator
123`\n`, `;` | Statement separators
124
125
126## Functions
127
128Functions are called by entering their name, followed by zero or more
129arguments enclosed by parentheses. All available functions are listed on the
130page [Functions](../reference/functions.md).
131
132```js
133math.evaluate('sqrt(25)') // 5
134math.evaluate('log(10000, 3 + 7)') // 4
135math.evaluate('sin(pi / 4)') // 0.7071067811865475
136```
137
138New functions can be defined using the `function` keyword. Functions can be
139defined with multiple variables. Function assignments are limited: they can
140only be defined on a single line.
141
142```js
143const parser = math.parser()
144
145parser.evaluate('f(x) = x ^ 2 - 5')
146parser.evaluate('f(2)') // -1
147parser.evaluate('f(3)') // 4
148
149parser.evaluate('g(x, y) = x ^ y')
150parser.evaluate('g(2, 3)') // 8
151```
152
153Math.js itself heavily uses typed functions, which ensure correct inputs and
154throws meaningful errors when the input arguments are invalid. One can create
155a [typed-function](https://github.com/josdejong/typed-function) in the
156expression parser like:
157
158```js
159const parser = math.parser()
160
161parser.evaluate('f = typed({"number": f(x) = x ^ 2 - 5})')
162```
163
164
165## Constants and variables
166
167Math.js has a number of built-in constants such as `pi` and `e`.
168All available constants are listed on he page
169[Constants](../reference/constants.md).
170
171```js
172// use constants
173math.evaluate('pi') // 3.141592653589793
174math.evaluate('e ^ 2') // 7.3890560989306495
175math.evaluate('log(e)') // 1
176math.evaluate('e ^ (pi * i) + 1') // ~0 (Euler)
177```
178
179Variables can be defined using the assignment operator `=`, and can be used
180like constants.
181
182```js
183const parser = math.parser()
184
185// define variables
186parser.evaluate('a = 3.4') // 3.4
187parser.evaluate('b = 5 / 2') // 2.5
188
189// use variables
190parser.evaluate('a * b') // 8.5
191```
192
193Variable names must:
194
195- Begin with an "alpha character", which is:
196 - A latin letter (upper or lower case). Ascii: `a-z`, `A-Z`
197 - An underscore. Ascii: `_`
198 - A dollar sign. Ascii: `$`
199 - A latin letter with accents. Unicode: `\u00C0` - `\u02AF`
200 - A greek letter. Unicode: `\u0370` - `\u03FF`
201 - A letter-like character. Unicode: `\u2100` - `\u214F`
202 - A mathematical alphanumeric symbol. Unicode: `\u{1D400}` - `\u{1D7FF}` excluding invalid code points
203- Contain only alpha characters (above) and digits `0-9`
204- Not be any of the following: `mod`, `to`, `in`, `and`, `xor`, `or`, `not`, `end`. It is possible to assign to some of these, but that's not recommended.
205
206It is possible to customize the allowed alpha characters, see [Customize supported characters](customization.md#customize-supported-characters) for more information.
207
208
209## Data types
210
211The expression parser supports booleans, numbers, complex numbers, units,
212strings, matrices, and objects.
213
214
215### Booleans
216
217Booleans `true` and `false` can be used in expressions.
218
219```js
220// use booleans
221math.evaluate('true') // true
222math.evaluate('false') // false
223math.evaluate('(2 == 3) == false') // true
224```
225
226Booleans can be converted to numbers and strings and vice versa using the
227functions `number` and `boolean`, and `string`.
228
229```js
230// convert booleans
231math.evaluate('number(true)') // 1
232math.evaluate('string(false)') // "false"
233math.evaluate('boolean(1)') // true
234math.evaluate('boolean("false")') // false
235```
236
237
238### Numbers
239
240The most important and basic data type in math.js are numbers. Numbers use a
241point as decimal mark. Numbers can be entered with exponential notation.
242Examples:
243
244```js
245// numbers in math.js
246math.evaluate('2') // 2
247math.evaluate('3.14') // 3.14
248math.evaluate('1.4e3') // 1400
249math.evaluate('22e-3') // 0.022
250```
251
252A number can be converted to a string and vice versa using the functions
253`number` and `string`.
254
255```js
256// convert a string into a number
257math.evaluate('number("2.3")') // 2.3
258math.evaluate('string(2.3)') // "2.3"
259```
260
261Math.js uses regular JavaScript numbers, which are floating points with a
262limited precision and limited range. The limitations are described in detail
263on the page [Numbers](../datatypes/numbers.md).
264
265```js
266math.evaluate('1e-325') // 0
267math.evaluate('1e309') // Infinity
268math.evaluate('-1e309') // -Infinity
269```
270
271When doing calculations with floats, one can very easily get round-off errors:
272
273```js
274// round-off error due to limited floating point precision
275math.evaluate('0.1 + 0.2') // 0.30000000000000004
276```
277
278When outputting results, the function `math.format` can be used to hide
279these round-off errors when outputting results for the user:
280
281```js
282const ans = math.evaluate('0.1 + 0.2') // 0.30000000000000004
283math.format(ans, {precision: 14}) // "0.3"
284```
285
286Numbers can be expressed as binary, octal, and hexadecimal literals:
287
288```js
289math.evaluate('0b11') // 3
290math.evaluate('0o77') // 63
291math.evaluate('0xff') // 255
292```
293
294A word size suffix can be used to change the behavior of non decimal literal evaluation:
295
296```js
297math.evaluate('0xffi8') // -1
298math.evaluate('0xffffffffi32') // -1
299math.evaluate('0xfffffffffi32') // SyntaxError: String "0xfffffffff" is out of range
300```
301
302Non decimal numbers can include a radix point:
303```js
304math.evaluate('0b1.1') // 1.5
305math.evaluate('0o1.4') // 1.5
306math.evaluate('0x1.8') // 1.5
307```
308
309Numbers can be formatted as binary, octal, and hex strings using the `notation` option of the `format` function:
310
311```js
312math.evaluate('format(3, {notation: "bin"})') // '0b11'
313math.evaluate('format(63, {notation: "oct"})') // '0o77'
314math.evaluate('format(255, {notation: "hex"})') // '0xff'
315math.evaluate('format(-1, {notation: "hex"})') // '-0x1'
316math.evaluate('format(2.3, {notation: "hex"})') // '0x2.4cccccccccccc'
317```
318
319The `format` function accepts a `wordSize` option to use in conjunction with the non binary notations:
320
321```js
322math.evaluate('format(-1, {notation: "hex", wordSize: 8})') // '0xffi8'
323```
324
325The functions `bin`, `oct`, and `hex` are shorthand for the `format` function with `notation` set accordingly:
326
327```js
328math.evaluate('bin(-1)') // '-0b1'
329math.evaluate('bin(-1, 8)') // '0b11111111i8'
330```
331
332### BigNumbers
333
334Math.js supports BigNumbers for calculations with an arbitrary precision.
335The pros and cons of Number and BigNumber are explained in detail on the page
336[Numbers](../datatypes/numbers.md).
337
338BigNumbers are slower but have a higher precision. Calculations with big
339numbers are supported only by arithmetic functions.
340
341BigNumbers can be created using the `bignumber` function:
342
343```js
344math.evaluate('bignumber(0.1) + bignumber(0.2)') // BigNumber, 0.3
345```
346
347The default number type of the expression parser can be changed at instantiation
348of math.js. The expression parser parses numbers as BigNumber by default:
349
350```js
351// Configure the type of number: 'number' (default), 'BigNumber', or 'Fraction'
352math.config({number: 'BigNumber'})
353
354// all numbers are parsed as BigNumber
355math.evaluate('0.1 + 0.2') // BigNumber, 0.3
356```
357
358BigNumbers can be converted to numbers and vice versa using the functions
359`number` and `bignumber`. When converting a BigNumber to a Number, the high
360precision of the BigNumber will be lost. When a BigNumber is too large to be represented
361as Number, it will be initialized as `Infinity`.
362
363
364### Complex numbers
365
366Complex numbers can be created using the imaginary unit `i`, which is defined
367as `i^2 = -1`. Complex numbers have a real and complex part, which can be
368retrieved using the functions `re` and `im`.
369
370```js
371const parser = math.parser()
372
373// create complex numbers
374parser.evaluate('a = 2 + 3i') // Complex, 2 + 3i
375parser.evaluate('b = 4 - i') // Complex, 4 - i
376
377// get real and imaginary part of a complex number
378parser.evaluate('re(a)') // Number, 2
379parser.evaluate('im(a)') // Number, 3
380
381// calculations with complex numbers
382parser.evaluate('a + b') // Complex, 6 + 2i
383parser.evaluate('a * b') // Complex, 11 + 10i
384parser.evaluate('i * i') // Number, -1
385parser.evaluate('sqrt(-4)') // Complex, 2i
386```
387
388Math.js does not automatically convert complex numbers with an imaginary part
389of zero to numbers. They can be converted to a number using the function
390`number`.
391
392```js
393// convert a complex number to a number
394const parser = math.parser()
395parser.evaluate('a = 2 + 3i') // Complex, 2 + 3i
396parser.evaluate('b = a - 3i') // Complex, 2 + 0i
397parser.evaluate('number(b)') // Number, 2
398parser.evaluate('number(a)') // Error: 2 + i is no valid number
399```
400
401
402### Units
403
404math.js supports units. Units can be used in the arithmetic operations
405add, subtract, multiply, divide, and exponentiation.
406Units can also be converted from one to another.
407An overview of all available units can be found on the page
408[Units](../datatypes/units.md).
409
410Units can be converted using the operator `to` or `in`.
411
412```js
413// create a unit
414math.evaluate('5.4 kg') // Unit, 5.4 kg
415
416// convert a unit
417math.evaluate('2 inch to cm') // Unit, 5.08 cm
418math.evaluate('20 celsius in fahrenheit') // Unit, ~68 fahrenheit
419math.evaluate('90 km/h to m/s') // Unit, 25 m / s
420
421// convert a unit to a number
422// A second parameter with the unit for the exported number must be provided
423math.evaluate('number(5 cm, mm)') // Number, 50
424
425// calculations with units
426math.evaluate('0.5kg + 33g') // Unit, 0.533 kg
427math.evaluate('3 inch + 2 cm') // Unit, 3.7874 inch
428math.evaluate('3 inch + 2 cm') // Unit, 3.7874 inch
429math.evaluate('12 seconds * 2') // Unit, 24 seconds
430math.evaluate('sin(45 deg)') // Number, 0.7071067811865475
431math.evaluate('9.81 m/s^2 * 5 s to mi/h') // Unit, 109.72172512527 mi / h
432```
433
434
435### Strings
436
437Strings are enclosed by double quotes " or single quotes '. Strings can be concatenated using the
438function `concat` (not by adding them using `+` like in JavaScript). Parts of
439a string can be retrieved or replaced by using indexes. Strings can be converted
440to a number using function `number`, and numbers can be converted to a string
441using function `string`.
442
443When setting the value of a character in a string, the character that has been
444set is returned. Likewise, when a range of characters is set, that range of
445characters is returned.
446
447
448```js
449const parser = math.parser()
450
451// create a string
452parser.evaluate('"hello"') // String, "hello"
453
454// string manipulation
455parser.evaluate('a = concat("hello", " world")') // String, "hello world"
456parser.evaluate('size(a)') // Matrix [11]
457parser.evaluate('a[1:5]') // String, "hello"
458parser.evaluate('a[1] = "H"') // String, "H"
459parser.evaluate('a[7:12] = "there!"') // String, "there!"
460parser.evaluate('a') // String, "Hello there!"
461
462// string conversion
463parser.evaluate('number("300")') // Number, 300
464parser.evaluate('string(300)') // String, "300"
465```
466
467Strings can be used in the `evaluate` function, to parse expressions inside
468the expression parser:
469
470```js
471math.evaluate('evaluate("2 + 3")') // 5
472```
473
474
475### Matrices
476
477Matrices can be created by entering a series of values between square brackets,
478elements are separated by a comma `,`.
479A matrix like `[1, 2, 3]` will create a vector, a 1-dimensional matrix with
480size `[3]`. To create a multi-dimensional matrix, matrices can be nested into
481each other. For easier creation of two-dimensional matrices, a semicolon `;`
482can be used to separate rows in a matrix.
483
484```js
485// create a matrix
486math.evaluate('[1, 2, 3]') // Matrix, size [3]
487math.evaluate('[[1, 2, 3], [4, 5, 6]]') // Matrix, size [2, 3]
488math.evaluate('[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]') // Matrix, size [2, 2, 2]
489
490// create a two dimensional matrix
491math.evaluate('[1, 2, 3; 4, 5, 6]') // Matrix, size [2, 3]
492```
493
494Another way to create filled matrices is using the functions `zeros`, `ones`,
495`identity`, and `range`.
496
497```js
498// initialize a matrix with ones or zeros
499math.evaluate('zeros(3, 2)') // Matrix, [[0, 0], [0, 0], [0, 0]], size [3, 2]
500math.evaluate('ones(3)') // Matrix, [1, 1, 1], size [3]
501math.evaluate('5 * ones(2, 2)') // Matrix, [[5, 5], [5, 5]], size [2, 2]
502
503// create an identity matrix
504math.evaluate('identity(2)') // Matrix, [[1, 0], [0, 1]], size [2, 2]
505
506// create a range
507math.evaluate('1:4') // Matrix, [1, 2, 3, 4], size [4]
508math.evaluate('0:2:10') // Matrix, [0, 2, 4, 6, 8, 10], size [6]
509```
510
511A subset can be retrieved from a matrix using indexes and a subset of a matrix
512can be replaced by using indexes. Indexes are enclosed in square brackets, and
513contain a number or a range for each of the matrix dimensions. A range can have
514its start and/or end undefined. When the start is undefined, the range will start
515at 1, when the end is undefined, the range will end at the end of the matrix.
516There is a context variable `end` available as well to denote the end of the
517matrix.
518
519*IMPORTANT: matrix indexes and ranges work differently from the math.js indexes
520in JavaScript: They are one-based with an included upper-bound, similar to most
521math applications.*
522
523```js
524parser = math.parser()
525
526// create matrices
527parser.evaluate('a = [1, 2; 3, 4]') // Matrix, [[1, 2], [3, 4]]
528parser.evaluate('b = zeros(2, 2)') // Matrix, [[0, 0], [0, 0]]
529parser.evaluate('c = 5:9') // Matrix, [5, 6, 7, 8, 9]
530
531// replace a subset in a matrix
532parser.evaluate('b[1, 1:2] = [5, 6]') // Matrix, [[5, 6], [0, 0]]
533parser.evaluate('b[2, :] = [7, 8]') // Matrix, [[5, 6], [7, 8]]
534
535// perform a matrix calculation
536parser.evaluate('d = a * b') // Matrix, [[19, 22], [43, 50]]
537
538// retrieve a subset of a matrix
539parser.evaluate('d[2, 1]') // 43
540parser.evaluate('d[2, 1:end]') // Matrix, [[43, 50]]
541parser.evaluate('c[end - 1 : -1 : 2]') // Matrix, [8, 7, 6]
542```
543
544## Objects
545
546Objects in math.js work the same as in languages like JavaScript and Python.
547An object is enclosed by square brackets `{`, `}`, and contains a set of
548comma separated key/value pairs. Keys and values are separated by a colon `:`.
549Keys can be a symbol like `prop` or a string like `"prop"`.
550
551```js
552math.evaluate('{a: 2 + 1, b: 4}') // {a: 3, b: 4}
553math.evaluate('{"a": 2 + 1, "b": 4}') // {a: 3, b: 4}
554```
555
556Objects can contain objects:
557
558```js
559math.evaluate('{a: 2, b: {c: 3, d: 4}}') // {a: 2, b: {c: 3, d: 4}}
560```
561
562Object properties can be retrieved or replaced using dot notation or bracket
563notation. Unlike JavaScript, when setting a property value, the whole object
564is returned, not the property value
565
566```js
567let scope = {
568 obj: {
569 prop: 42
570 }
571}
572
573// retrieve properties
574math.evaluate('obj.prop', scope) // 42
575math.evaluate('obj["prop"]', scope) // 42
576
577// set properties (returns the whole object, not the property value!)
578math.evaluate('obj.prop = 43', scope) // {prop: 43}
579math.evaluate('obj["prop"] = 43', scope) // {prop: 43}
580scope.obj // {prop: 43}
581```
582
583
584## Multi-line expressions
585
586An expression can contain multiple lines, and expressions can be spread over
587multiple lines. Lines can be separated by a newline character `\n` or by a
588semicolon `;`. Output of statements followed by a semicolon will be hidden from
589the output, and empty lines are ignored. The output is returned as a `ResultSet`,
590with an entry for every visible statement.
591
592```js
593// a multi-line expression
594math.evaluate('1 * 3 \n 2 * 3 \n 3 * 3') // ResultSet, [3, 6, 9]
595
596// semicolon statements are hidden from the output
597math.evaluate('a=3; b=4; a + b \n a * b') // ResultSet, [7, 12]
598
599// single expression spread over multiple lines
600math.evaluate('a = 2 +\n 3') // 5
601math.evaluate('[\n 1, 2;\n 3, 4\n]') // Matrix, [[1, 2], [3, 4]]
602```
603
604The results can be read from a `ResultSet` via the property `ResultSet.entries`
605which is an `Array`, or by calling `ResultSet.valueOf()`, which returns the
606array with results.
607
608
609## Implicit multiplication
610
611*Implicit multiplication* means the multiplication of two symbols, numbers, or a grouped expression inside parentheses without using the `*` operator. This type of syntax allows a more natural way to enter expressions. For example:
612
613```js
614math.evaluate('2 pi') // 6.283185307179586
615math.evaluate('(1+2)(3+4)') // 21
616```
617
618Parentheses are parsed as a function call when there is a symbol or accessor on
619the left hand side, like `sqrt(4)` or `obj.method(4)`. In other cases the
620parentheses are interpreted as an implicit multiplication.
621
622Math.js will always evaluate implicit multiplication before explicit multiplication `*`, so that the expression `x * y z` is parsed as `x * (y * z)`. Math.js also gives implicit multiplication higher precedence than division, *except* when the division matches the pattern `[number] / [number] [symbol]` or `[number] / [number] [left paren]`. In that special case, the division is evaluated first:
623
624```js
625math.evaluate('20 kg / 4 kg') // 5 Evaluated as (20 kg) / (4 kg)
626math.evaluate('20 / 4 kg') // 5 kg Evaluated as (20 / 4) kg
627```
628
629The behavior of implicit multiplication can be summarized by these operator precedence rules, listed from highest to lowest precedence:
630
631- Function calls: `[symbol] [left paren]`
632- Explicit division `/` when the division matches this pattern: `[number] / [number] [symbol]` or `[number] / [number] [left paren]`
633- Implicit multiplication
634- All other division `/` and multiplication `*`
635
636Implicit multiplication is tricky as there can appear to be ambiguity in how an expression will be evaluated. Experience has shown that the above rules most closely match user intent when entering expressions that could be interpreted different ways. It's also possible that these rules could be tweaked in future major releases. Use implicit multiplication carefully. If you don't like the uncertainty introduced by implicit multiplication, use explicit `*` operators and parentheses to ensure your expression is evaluated the way you intend.
637
638Here are some more examples using implicit multiplication:
639
640Expression | Evaluated as | Result
641--------------- | ------------------- | ------------------
642(1 + 3) pi | (1 + 3) * pi | 12.566370614359172
643(4 - 1) 2 | (4 - 1) * 2 | 6
6443 / 4 mm | (3 / 4) * mm | 0.75 mm
6452 + 3 i | 2 + (3 * i) | 2 + 3i
646(1 + 2) (4 - 2) | (1 + 2) * (4 - 2) | 6
647sqrt(4) (1 + 2) | sqrt(4) * (1 + 2) | 6
6488 pi / 2 pi | (8 * pi) / (2 * pi) | 4
649pi / 2 pi | pi / (2 * pi) | 0.5
6501 / 2i | (1 / 2) * i | 0.5 i
6518.314 J / mol K | 8.314 J / (mol * K) | 8.314 J / (mol * K)
652
653
654## Comments
655
656Comments can be added to explain or describe calculations in the text. A comment
657starts with a sharp sign character `#`, and ends at the end of the line. A line
658can contain a comment only, or can contain an expression followed by a comment.
659
660```js
661const parser = math.parser()
662
663parser.evaluate('# define some variables')
664parser.evaluate('width = 3') // 3
665parser.evaluate('height = 4') // 4
666parser.evaluate('width * height # calculate the area') // 12
667```