Skip to content

Commit c87c980

Browse files
committed
fix: Uniformize bigint construction
Adds options to the bigint constructor function `math.bigint()` to control whether/how non-integer inputs are rounded or errors thrown, and whether "unsafe" values outside the range where integers can be uniquely represented are converted. Changes `math.numeric(x, 'bigint')` to call the bigint constructor configured to allow unsafe values but throw on non-integers (closest approximation to its previous buggy behavior). Also restores documentation generation for constructor functions, and initiates History sections in function doc pages. Resolves #3366. Resolves #3368. Resolves #3341.
1 parent 6535aba commit c87c980

File tree

22 files changed

+481
-92
lines changed

22 files changed

+481
-92
lines changed

src/core/function/import.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,26 @@ export function importFactory (typed, load, math, importedFactories) {
4545
* return 'hello, ' + name + '!'
4646
* }
4747
* })
48-
*
49-
* // use the imported function and variable
48+
* // use the imported function and variable
5049
* math.myvalue * 2 // 84
50+
*
5151
* math.hello('user') // 'hello, user!'
5252
*
5353
* // import the npm module 'numbers'
5454
* // (must be installed first with `npm install numbers`)
5555
* math.import(numbers, {wrap: true})
56-
*
5756
* math.fibonacci(7) // returns 13
5857
*
58+
* See also:
59+
*
60+
* create, all
61+
*
62+
* History:
63+
*
64+
* v0.2 Created
65+
* v0.7 Changed second parameter to an options object
66+
* v2 Dropped support for direct import of a module by name
67+
*
5968
* @param {Object | Array} functions Object with functions to be imported.
6069
* @param {Object} [options] Import options.
6170
*/

src/expression/parse.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,35 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
6666
* node1.compile().evaluate() // 5
6767
*
6868
* let scope = {a:3, b:4}
69-
* const node2 = math.parse('a * b') // 12
69+
* const node2 = math.parse('a * b')
70+
* node2.evaluate(scope) // 12
7071
* const code2 = node2.compile()
71-
* code2.evaluate(scope) // 12
72+
* scope.b = 5
73+
* code2.evaluate(scope) // 15
7274
* scope.a = 5
73-
* code2.evaluate(scope) // 20
75+
* code2.evaluate(scope) // 25
7476
*
75-
* const nodes = math.parse(['a = 3', 'b = 4', 'a * b'])
76-
* nodes[2].compile().evaluate() // 12
77+
* const nodes = math.parse(['a = 3', 'b = 2', 'a * b'])
78+
* const newscope = {}
79+
* nodes.map(node => node.compile().evaluate(newscope)) // [3, 2, 6]
7780
*
7881
* See also:
7982
*
8083
* evaluate, compile
8184
*
85+
* History:
86+
*
87+
* v0.9 Created
88+
* v0.13 Switched to one-based indices
89+
* v0.14 Added `[1,2;3,4]` notation for matrices
90+
* v0.18 Dropped the `function` keyword
91+
* v0.20 Added ternary conditional
92+
* v0.27 Allow multi-line expressions; allow functions that receive
93+
* unevaluated parameters (`rawArgs`)
94+
* v3 Add object notation; allow assignments internal to other
95+
* expressions
96+
* v7.3 Supported binary, octal, and hexadecimal notation
97+
*
8298
* @param {string | string[] | Matrix} expr Expression to be parsed
8399
* @param {{nodes: Object<string, Node>}} [options] Available options:
84100
* - `nodes` a set of custom nodes

src/function/algebra/polynomialRoot.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,17 @@ export const createPolynomialRoot = /* #__PURE__ */ factory(name, dependencies,
4242
* math.polynomialRoot(constant, linearCoeff, quadraticCoeff, cubicCoeff)
4343
*
4444
* Examples:
45-
* // linear
45+
* // linear
4646
* math.polynomialRoot(6, 3) // [-2]
4747
* math.polynomialRoot(math.complex(6,3), 3) // [-2 - i]
4848
* math.polynomialRoot(math.complex(6,3), math.complex(2,1)) // [-3 + 0i]
49-
* // quadratic
49+
* // quadratic
5050
* math.polynomialRoot(2, -3, 1) // [2, 1]
5151
* math.polynomialRoot(8, 8, 2) // [-2]
5252
* math.polynomialRoot(-2, 0, 1) // [1.4142135623730951, -1.4142135623730951]
5353
* math.polynomialRoot(2, -2, 1) // [1 + i, 1 - i]
5454
* math.polynomialRoot(math.complex(1,3), math.complex(-3, -2), 1) // [2 + i, 1 + i]
55-
* // cubic
55+
* // cubic
5656
* math.polynomialRoot(-6, 11, -6, 1) // [1, 3, 2]
5757
* math.polynomialRoot(-8, 0, 0, 1) // [-1 - 1.7320508075688774i, 2, -1 + 1.7320508075688774i]
5858
* math.polynomialRoot(0, 8, 8, 2) // [0, -2]
@@ -61,6 +61,10 @@ export const createPolynomialRoot = /* #__PURE__ */ factory(name, dependencies,
6161
* See also:
6262
* cbrt, sqrt
6363
*
64+
* History:
65+
*
66+
* v11.4 Created
67+
*
6468
* @param {... number | Complex} coeffs
6569
* The coefficients of the polynomial, starting with with the constant coefficent, followed
6670
* by the linear coefficient and subsequent coefficients of increasing powers.

src/function/arithmetic/log.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ export const createLog = /* #__PURE__ */ factory(name, dependencies, ({ typed, t
1313
* To avoid confusion with the matrix logarithm, this function does not
1414
* apply to matrices.
1515
*
16+
* Note that when the value is a Fraction, then the
17+
* base must be specified as a Fraction, and the log() will only be
18+
* returned when the result happens to be rational. When there is an
19+
* attempt to take a log of Fractions that would result in an irrational
20+
* value, a TypeError against implicit conversion of BigInt to Fraction
21+
* is thrown.
22+
*
1623
* Syntax:
1724
*
1825
* math.log(x)
@@ -34,11 +41,25 @@ export const createLog = /* #__PURE__ */ factory(name, dependencies, ({ typed, t
3441
*
3542
* exp, log2, log10, log1p
3643
*
44+
* History:
45+
*
46+
* v0.0.2 Created
47+
* v0.2 Add optional base argument
48+
* v0.3 Handle Array input
49+
* v0.5 Handle Matrix input
50+
* v0.16 Handle BigNumber input
51+
* v0.21 Support negative BigNumbers
52+
* v11 Drop Array/Matrix support in favor of explicit map of
53+
* the scalar log function, to avoid confusion with the log
54+
* of a matrix
55+
* v14 Allow value and base to be Fractions, when the log is rational
56+
*
3757
* @param {number | BigNumber | Fraction | Complex} x
3858
* Value for which to calculate the logarithm.
3959
* @param {number | BigNumber | Fraction | Complex} [base=e]
4060
* Optional base for the logarithm. If not provided, the natural
41-
* logarithm of `x` is calculated.
61+
* logarithm of `x` is calculated, unless x is a Fraction, in
62+
* which case an error is thrown.
4263
* @return {number | BigNumber | Fraction | Complex}
4364
* Returns the logarithm of `x`
4465
*/

src/function/matrix/map.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,19 @@ export const createMap = /* #__PURE__ */ factory(name, dependencies, ({ typed })
3838
* // callback(value, index, Array)
3939
* // If you want to call with only one argument, use:
4040
* math.map([1, 2, 3], x => math.format(x)) // returns ['1', '2', '3']
41-
* // It can also be called with 2N + 1 arguments: for N arrays
42-
* // callback(value1, value2, index, BroadcastedArray1, BroadcastedArray2)
41+
* // It can also be called with 2N + 1 arguments: for N arrays
42+
* // callback(value1, value2, index, BroadcastedArray1, BroadcastedArray2)
4343
*
4444
* See also:
4545
*
4646
* filter, forEach, sort
4747
*
48+
* History:
49+
*
50+
* v0.13 Created
51+
* v1.1 Clone the indices on each callback in case callback mutates
52+
* v13.1 Support multiple inputs to the callback
53+
*
4854
* @param {Matrix | Array} x The input to iterate on.
4955
* @param {Function} callback
5056
* The function to call (as described above) on each entry of the input

src/function/relational/compare.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ export const createCompare = /* #__PURE__ */ factory(name, dependencies, ({ type
5858
*
5959
* equal, unequal, smaller, smallerEq, larger, largerEq, compareNatural, compareText
6060
*
61+
* History:
62+
*
63+
* v0.19 Created
64+
* v4 Changed to compare strings by numerical value
65+
*
6166
* @param {number | BigNumber | bigint | Fraction | Unit | string | Array | Matrix} x First value to compare
6267
* @param {number | BigNumber | bigint | Fraction | Unit | string | Array | Matrix} y Second value to compare
6368
* @return {number | BigNumber | bigint | Fraction | Array | Matrix} Returns the result of the comparison:

src/function/string/format.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ export const createFormat = /* #__PURE__ */ factory(name, dependencies, ({ typed
109109
* function formatCurrency(value) {
110110
* // return currency notation with two digits:
111111
* return '$' + value.toFixed(2)
112-
*
113112
* // you could also use math.format inside the callback:
114113
* // return '$' + math.format(value, {notation: 'fixed', precision: 2})
115114
* }
@@ -119,6 +118,14 @@ export const createFormat = /* #__PURE__ */ factory(name, dependencies, ({ typed
119118
*
120119
* print
121120
*
121+
* History:
122+
*
123+
* v0.4 Created
124+
* v0.7 Round to a consistent number of digits (rather than decimals)
125+
* v0.15 Added multiple number notations and configurable precision
126+
* v3 Added support for JSON objects
127+
* v9 Added binary, hexadecimal, and octal notations
128+
*
122129
* @param {*} value Value to be stringified
123130
* @param {Object | Function | number} [options] Formatting options
124131
* @return {string} The formatted value

src/function/utils/numeric.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import { factory } from '../../utils/factory.js'
33
import { noBignumber, noFraction } from '../../utils/noop.js'
44

55
const name = 'numeric'
6-
const dependencies = ['number', '?bignumber', '?fraction']
6+
const dependencies = ['number', 'bigint', '?bignumber', '?fraction']
77

8-
export const createNumeric = /* #__PURE__ */ factory(name, dependencies, ({ number, bignumber, fraction }) => {
8+
export const createNumeric = /* #__PURE__ */ factory(name, dependencies, ({ number, bigint, bignumber, fraction }) => {
99
const validInputTypes = {
1010
string: true,
1111
number: true,
12+
bigint: true,
1213
BigNumber: true,
1314
Fraction: true
1415
}
@@ -19,7 +20,7 @@ export const createNumeric = /* #__PURE__ */ factory(name, dependencies, ({ numb
1920
BigNumber: bignumber
2021
? (x) => bignumber(x)
2122
: noBignumber,
22-
bigint: (x) => BigInt(x),
23+
bigint: (x) => bigint(x, { round: 'throw', safe: false }),
2324
Fraction: fraction
2425
? (x) => fraction(x)
2526
: noFraction
@@ -46,6 +47,12 @@ export const createNumeric = /* #__PURE__ */ factory(name, dependencies, ({ numb
4647
*
4748
* number, fraction, bignumber, bigint, string, format
4849
*
50+
* History:
51+
*
52+
* v6 Created
53+
* v13 Added `bigint` support
54+
* v14.2.1 Prefer mathjs `bigint()` to built-in `BigInt()`
55+
*
4956
* @param {string | number | BigNumber | bigint | Fraction } value
5057
* A numeric value or a string containing a numeric value
5158
* @param {string} outputType

0 commit comments

Comments
 (0)