1 | # Numbers
|
2 |
|
3 | Math.js supports three types of numbers:
|
4 |
|
5 | - Number for fast floating point arithmetic, described on this page.
|
6 | - BigNumber for arbitrary precision arithmetic, described on the page
|
7 | [BigNumbers](bignumbers.md).
|
8 | - Fraction, which stores numbers in terms of a numerator and denominators,
|
9 | described on the page [Fractions](fractions.md).
|
10 |
|
11 |
|
12 | ## Configuration
|
13 |
|
14 | Most functions can determine the type of output from the type of input:
|
15 | a number as input will return a number as output, a BigNumber as input returns
|
16 | a BigNumber as output. Functions which cannot determine the type of output
|
17 | from the input (for example `math.evaluate`) use the default number type, which
|
18 | can be configured when instantiating math.js:
|
19 |
|
20 | ```js
|
21 | math.config({
|
22 | number: 'number' // Default type of number:
|
23 | // 'number' (default), 'BigNumber', or 'Fraction'
|
24 | })
|
25 | ```
|
26 |
|
27 | ## Round-off errors
|
28 |
|
29 | Math.js uses the built-in JavaScript Number type. A Number is a floating point
|
30 | number with a limited precision of 64 bits, about 16 digits. The largest integer
|
31 | number which can be represented by a JavaScript Number
|
32 | is `+/- 9007199254740992` (`+/- 2^53`). Because of the limited precision of
|
33 | floating point numbers round-off errors can occur during calculations.
|
34 | This can be easily demonstrated:
|
35 |
|
36 | ```js
|
37 | // a round-off error
|
38 | 0.1 + 0.2 // 0.30000000000000004
|
39 | math.add(0.1, 0.2) // 0.30000000000000004
|
40 | ```
|
41 |
|
42 | In most cases, round-off errors don't matter: they have no significant
|
43 | impact on the results. However, it looks ugly when displaying output to a user.
|
44 | A solution is to limit the precision just below the actual precision of 16
|
45 | digits in the displayed output:
|
46 |
|
47 | ```js
|
48 | // prevent round-off errors showing up in output
|
49 | const ans = math.add(0.1, 0.2) // 0.30000000000000004
|
50 | math.format(ans, {precision: 14}) // '0.3'
|
51 | ```
|
52 |
|
53 | Alternatives are to use [Fractions](fractions.md) which store a number as a numerator and denominator, or [BigNumbers](bignumbers.md), which store a number with a higher precision.
|
54 |
|
55 |
|
56 | ## Minimum and maximum
|
57 |
|
58 | A Number can store values between `5e-324` and `1.7976931348623157e+308`.
|
59 | Values smaller than the minimum are stored as `0`, and values larger than the
|
60 | maximum are stored as `+/- Infinity`.
|
61 |
|
62 | ```js
|
63 | // exceeding the maximum and minimum number
|
64 | console.log(1e309) // Infinity
|
65 | console.log(1e-324) // 0
|
66 | ```
|
67 |
|
68 | ## Equality
|
69 |
|
70 | Because of rounding errors in calculations, it is unsafe to compare JavaScript
|
71 | Numbers. For example executing `0.1 + 0.2 == 0.3` in JavaScript will return
|
72 | false, as the addition `0.1 + 0.2` introduces a round-off error and does not
|
73 | return exactly `0.3`.
|
74 |
|
75 | To solve this problem, the relational functions of math.js check whether the
|
76 | relative difference between the compared values is smaller than the configured
|
77 | option `epsilon`. In pseudo code (without exceptions for 0, Infinity and NaN):
|
78 |
|
79 | diff = abs(x - y)
|
80 | nearlyEqual = (diff <= max(abs(x), abs(y)) * EPSILON) OR (diff < DBL_EPSILON)
|
81 |
|
82 | where:
|
83 |
|
84 | - `EPSILON` is the relative difference between x and y. Epsilon is configurable
|
85 | and is `1e-12` by default. See [Configuration](../core/configuration.md).
|
86 | - `DBL_EPSILON` is the minimum positive floating point number such that
|
87 | `1.0 + DBL_EPSILON !== 1.0`. This is a constant with a value of approximately
|
88 | `2.2204460492503130808472633361816e-16`.
|
89 |
|
90 | Note that the relational functions cannot be used to compare small values
|
91 | (`< 2.22e-16`). These values are all considered equal to zero.
|
92 |
|
93 | Examples:
|
94 |
|
95 | ```js
|
96 | // compare values having a round-off error
|
97 | console.log(0.1 + 0.2 === 0.3) // false
|
98 | console.log(math.equal(0.1 + 0.2, 0.3)) // true
|
99 |
|
100 | // small values (< 2.22e-16) cannot be compared
|
101 | console.log(3e-20 === 3.1e-20) // false
|
102 | console.log(math.equal(3e-20, 3.1e-20)) // true
|
103 | ```
|
104 |
|
105 | The available relational functions are: `compare`, `equal`, `larger`,
|
106 | `largerEq`, `smaller`, `smallerEq`, `unequal`.
|