1 | # BigNumbers
|
2 |
|
3 | For calculations with an arbitrary precision, math.js supports a `BigNumber`
|
4 | datatype. BigNumber support is powered by
|
5 | [decimal.js](https://github.com/MikeMcl/decimal.js/).
|
6 |
|
7 | ## Usage
|
8 |
|
9 | A BigNumber can be created using the function `bignumber`:
|
10 |
|
11 | ```js
|
12 | math.bignumber('2.3e+500') // BigNumber, 2.3e+500
|
13 | ```
|
14 |
|
15 | Most functions can determine the type of output from the type of input:
|
16 | a number as input will return a number as output, a BigNumber as input returns
|
17 | a BigNumber as output. Functions which cannot determine the type of output
|
18 | from the input (for example `math.evaluate`) use the default number type `number`,
|
19 | which can be configured when instantiating math.js. To configure the use of
|
20 | BigNumbers instead of [numbers](numbers.md) by default, configure math.js like:
|
21 |
|
22 | ```js
|
23 | math.config({
|
24 | number: 'BigNumber', // Default type of number:
|
25 | // 'number' (default), 'BigNumber', or 'Fraction'
|
26 | precision: 64 // Number of significant digits for BigNumbers
|
27 | })
|
28 |
|
29 | // use math
|
30 | math.evaluate('0.1 + 0.2') // BigNumber, 0.3
|
31 | ```
|
32 |
|
33 | The default precision for BigNumber is 64 digits, and can be configured with
|
34 | the option `precision`.
|
35 |
|
36 |
|
37 | ## Support
|
38 |
|
39 | Most functions in math.js support BigNumbers, but not all of them.
|
40 | For example the function `random` doesn't support BigNumbers.
|
41 |
|
42 |
|
43 | ## Round-off errors
|
44 |
|
45 | Calculations with BigNumber are much slower than calculations with Number,
|
46 | but they can be executed with an arbitrary precision. By using a higher
|
47 | precision, it is less likely that round-off errors occur:
|
48 |
|
49 | ```js
|
50 | // round-off errors with numbers
|
51 | math.add(0.1, 0.2) // Number, 0.30000000000000004
|
52 | math.divide(0.3, 0.2) // Number, 1.4999999999999998
|
53 |
|
54 | // no round-off errors with BigNumbers :)
|
55 | math.add(math.bignumber(0.1), math.bignumber(0.2)) // BigNumber, 0.3
|
56 | math.divide(math.bignumber(0.3), math.bignumber(0.2)) // BigNumber, 1.5
|
57 | ```
|
58 |
|
59 |
|
60 | ## Limitations
|
61 |
|
62 | It's important to realize that BigNumbers do not solve *all* problems related
|
63 | to precision and round-off errors. Numbers with an infinite number of digits
|
64 | cannot be represented with a regular number nor a BigNumber. Though a BigNumber
|
65 | can store a much larger number of digits, the amount of digits remains limited
|
66 | if only to keep calculations fast enough to remain practical.
|
67 |
|
68 | ```js
|
69 | const one = math.bignumber(1)
|
70 | const three = math.bignumber(3)
|
71 | const third = math.divide(one, three)
|
72 | console.log(third.toString())
|
73 | // outputs 0.3333333333333333333333333333333333333333333333333333333333333333
|
74 |
|
75 | const ans = math.multiply(third, three)
|
76 | console.log(ans.toString())
|
77 | // outputs 0.9999999999999999999999999999999999999999999999999999999999999999
|
78 | // this should be 1 again, but `third` is rounded to a limited number of digits 3
|
79 | ```
|
80 |
|
81 |
|
82 | ## Conversion
|
83 |
|
84 | BigNumbers can be converted to numbers and vice versa using the functions
|
85 | `number` and `bignumber`. When converting a BigNumber to a number, the high
|
86 | precision of the BigNumber will be lost. When a BigNumber is too large to be represented
|
87 | as Number, it will be initialized as `Infinity`.
|
88 |
|
89 | ```js
|
90 | // converting numbers and BigNumbers
|
91 | const a = math.number(0.3) // number, 0.3
|
92 | const b = math.bignumber(a) // BigNumber, 0.3
|
93 | const c = math.number(b) // number, 0.3
|
94 |
|
95 | // exceeding the maximum of a number
|
96 | const d = math.bignumber('1.2e500') // BigNumber, 1.2e+500
|
97 | const e = math.number(d) // number, Infinity
|
98 |
|
99 | // loosing precision when converting to number
|
100 | const f = math.bignumber('0.2222222222222222222') // BigNumber, 0.2222222222222222222
|
101 | const g = math.number(f) // number, 0.2222222222222222
|
102 | ```
|