Comparing version 5.2.2 to 6.0.0
355
big.js
/* | ||
* big.js v5.2.2 | ||
* big.js v6.0.0 | ||
* A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic. | ||
* Copyright (c) 2018 Michael Mclaughlin <M8ch88l@gmail.com> | ||
* https://github.com/MikeMcl/big.js/LICENCE | ||
* Copyright (c) 2020 Michael Mclaughlin | ||
* https://github.com/MikeMcl/big.js/LICENCE.md | ||
*/ | ||
@@ -21,3 +21,3 @@ ;(function (GLOBAL) { | ||
*/ | ||
DP = 20, // 0 to MAX_DP | ||
DP = 20, // 0 to MAX_DP | ||
@@ -50,8 +50,14 @@ /* | ||
* (JavaScript numbers: 21) | ||
* 1000000 is the maximum recommended exponent value of a Big. | ||
* (This limit is not enforced or checked.) | ||
* 1000000 is the maximum recommended exponent value of a Big, but this limit is not enforced. | ||
*/ | ||
PE = 21, // 0 to 1000000 | ||
/* | ||
* When true, an error will be thrown if a primitive number is passed to the Big constructor, | ||
* or if valueOf is called, or if toNumber is called on a Big which cannot be converted to a | ||
* primitive number without a loss of precision. | ||
*/ | ||
STRICT = false, // true or false | ||
/**************************************************************************************************/ | ||
@@ -75,3 +81,2 @@ | ||
* Create and return a Big constructor. | ||
* | ||
*/ | ||
@@ -98,9 +103,16 @@ function _Big_() { | ||
} else { | ||
if (typeof n !== 'string') { | ||
if (Big.strict === true) { | ||
throw TypeError(INVALID + 'number'); | ||
} | ||
// Minus zero? | ||
n = n === 0 && 1 / n < 0 ? '-0' : String(n); | ||
} | ||
parse(x, n); | ||
} | ||
/* | ||
* Retain a reference to this Big constructor, and shadow Big.prototype.constructor which | ||
* points to Object. | ||
*/ | ||
// Retain a reference to this Big constructor. | ||
// Shadow Big.prototype.constructor which points to Object. | ||
x.constructor = Big; | ||
@@ -114,3 +126,3 @@ } | ||
Big.PE = PE; | ||
Big.version = '5.2.2'; | ||
Big.strict = STRICT; | ||
@@ -130,5 +142,5 @@ return Big; | ||
// Minus zero? | ||
if (n === 0 && 1 / n < 0) n = '-0'; | ||
else if (!NUMERIC.test(n += '')) throw Error(INVALID + 'number'); | ||
if (!NUMERIC.test(n)) { | ||
throw Error(INVALID + 'number'); | ||
} | ||
@@ -179,65 +191,63 @@ // Determine sign. | ||
/* | ||
* Round Big x to a maximum of dp decimal places using rounding mode rm. | ||
* Called by stringify, P.div, P.round and P.sqrt. | ||
* Round Big x to a maximum of sd significant digits using rounding mode rm. | ||
* | ||
* x {Big} The Big to round. | ||
* dp {number} Integer, 0 to MAX_DP inclusive. | ||
* rm {number} 0, 1, 2 or 3 (DOWN, HALF_UP, HALF_EVEN, UP) | ||
* sd {number} Significant digits: integer, 0 to MAX_DP inclusive. | ||
* rm {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). | ||
* [more] {boolean} Whether the result of division was truncated. | ||
*/ | ||
function round(x, dp, rm, more) { | ||
var xc = x.c, | ||
i = x.e + dp + 1; | ||
function round(x, sd, rm, more) { | ||
var xc = x.c; | ||
if (i < xc.length) { | ||
if (rm === 1) { | ||
if (rm === UNDEFINED) rm = Big.RM; | ||
if (rm !== 0 && rm !== 1 && rm !== 2 && rm !== 3) { | ||
throw Error(INVALID_RM); | ||
} | ||
// xc[i] is the digit after the digit that may be rounded up. | ||
more = xc[i] >= 5; | ||
} else if (rm === 2) { | ||
more = xc[i] > 5 || xc[i] == 5 && | ||
(more || i < 0 || xc[i + 1] !== UNDEFINED || xc[i - 1] & 1); | ||
} else if (rm === 3) { | ||
more = more || !!xc[0]; | ||
} else { | ||
more = false; | ||
if (rm !== 0) throw Error(INVALID_RM); | ||
} | ||
if (sd < 1) { | ||
more = | ||
rm === 3 && (more || !!xc[0]) || sd === 0 && ( | ||
rm === 1 && xc[0] >= 5 || | ||
rm === 2 && (xc[0] > 5 || xc[0] === 5 && (more || xc[1] !== UNDEFINED)) | ||
); | ||
if (i < 1) { | ||
xc.length = 1; | ||
xc.length = 1; | ||
if (more) { | ||
if (more) { | ||
// 1, 0.1, 0.01, 0.001, 0.0001 etc. | ||
x.e = -dp; | ||
xc[0] = 1; | ||
} else { | ||
// Zero. | ||
xc[0] = x.e = 0; | ||
} | ||
// 1, 0.1, 0.01, 0.001, 0.0001 etc. | ||
x.e = x.e - sd + 1; | ||
xc[0] = 1; | ||
} else { | ||
// Remove any digits after the required decimal places. | ||
xc.length = i--; | ||
// Zero. | ||
xc[0] = x.e = 0; | ||
} | ||
} else if (sd < xc.length) { | ||
// Round up? | ||
if (more) { | ||
// xc[sd] is the digit after the digit that may be rounded up. | ||
more = | ||
rm === 1 && xc[sd] >= 5 || | ||
rm === 2 && (xc[sd] > 5 || xc[sd] === 5 && | ||
(more || xc[sd + 1] !== UNDEFINED || xc[sd - 1] & 1)) || | ||
rm === 3 && (more || !!xc[0]); | ||
// Rounding up may mean the previous digit has to be rounded up. | ||
for (; ++xc[i] > 9;) { | ||
xc[i] = 0; | ||
if (!i--) { | ||
++x.e; | ||
xc.unshift(1); | ||
} | ||
// Remove any digits after the required precision. | ||
xc.length = sd--; | ||
// Round up? | ||
if (more) { | ||
// Rounding up may mean the previous digit has to be rounded up. | ||
for (; ++xc[sd] > 9;) { | ||
xc[sd] = 0; | ||
if (!sd--) { | ||
++x.e; | ||
xc.unshift(1); | ||
} | ||
} | ||
} | ||
// Remove trailing zeros. | ||
for (i = xc.length; !xc[--i];) xc.pop(); | ||
} | ||
} else if (rm < 0 || rm > 3 || rm !== ~~rm) { | ||
throw Error(INVALID_RM); | ||
// Remove trailing zeros. | ||
for (sd = xc.length; !xc[--sd];) xc.pop(); | ||
} | ||
@@ -252,43 +262,10 @@ | ||
* Handles P.toExponential, P.toFixed, P.toJSON, P.toPrecision, P.toString and P.valueOf. | ||
* | ||
* x {Big} | ||
* id? {number} Caller id. | ||
* 1 toExponential | ||
* 2 toFixed | ||
* 3 toPrecision | ||
* 4 valueOf | ||
* n? {number|undefined} Caller's argument. | ||
* k? {number|undefined} | ||
*/ | ||
function stringify(x, id, n, k) { | ||
var e, s, | ||
Big = x.constructor, | ||
z = !x.c[0]; | ||
function stringify(x, doExponential, isNonzero) { | ||
var e = x.e, | ||
s = x.c.join(''), | ||
n = s.length; | ||
if (n !== UNDEFINED) { | ||
if (n !== ~~n || n < (id == 3) || n > MAX_DP) { | ||
throw Error(id == 3 ? INVALID + 'precision' : INVALID_DP); | ||
} | ||
x = new Big(x); | ||
// The index of the digit that may be rounded up. | ||
n = k - x.e; | ||
// Round? | ||
if (x.c.length > ++k) round(x, n, Big.RM); | ||
// toFixed: recalculate k as x.e may have changed if value rounded up. | ||
if (id == 2) k = x.e + n + 1; | ||
// Append zeros? | ||
for (; x.c.length < k;) x.c.push(0); | ||
} | ||
e = x.e; | ||
s = x.c.join(''); | ||
n = s.length; | ||
// Exponential notation? | ||
if (id != 2 && (id == 1 || id == 3 && k <= e || e <= Big.NE || e >= Big.PE)) { | ||
if (doExponential) { | ||
s = s.charAt(0) + (n > 1 ? '.' + s.slice(1) : '') + (e < 0 ? 'e' : 'e+') + e; | ||
@@ -301,4 +278,7 @@ | ||
} else if (e > 0) { | ||
if (++e > n) for (e -= n; e--;) s += '0'; | ||
else if (e < n) s = s.slice(0, e) + '.' + s.slice(e); | ||
if (++e > n) { | ||
for (e -= n; e--;) s += '0'; | ||
} else if (e < n) { | ||
s = s.slice(0, e) + '.' + s.slice(e); | ||
} | ||
} else if (n > 1) { | ||
@@ -308,3 +288,3 @@ s = s.charAt(0) + '.' + s.slice(1); | ||
return x.s < 0 && (!z || id == 4) ? '-' + s : s; | ||
return x.s < 0 && isNonzero ? '-' + s : s; | ||
} | ||
@@ -330,3 +310,3 @@ | ||
* 0 if they have the same value. | ||
*/ | ||
*/ | ||
P.cmp = function (y) { | ||
@@ -377,6 +357,10 @@ var isneg, | ||
if (dp !== ~~dp || dp < 0 || dp > MAX_DP) throw Error(INVALID_DP); | ||
if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { | ||
throw Error(INVALID_DP); | ||
} | ||
// Divisor is zero? | ||
if (!b[0]) throw Error(DIV_BY_ZERO); | ||
if (!b[0]) { | ||
throw Error(DIV_BY_ZERO); | ||
} | ||
@@ -395,6 +379,6 @@ // Dividend is 0? Return +-0. | ||
qi = 0, | ||
d = dp + (q.e = x.e - y.e) + 1; // number of digits of the result | ||
p = dp + (q.e = x.e - y.e) + 1; // precision of the result | ||
q.s = k; | ||
k = d < 0 ? 0 : d; | ||
k = p < 0 ? 0 : p; | ||
@@ -460,6 +444,7 @@ // Create version of divisor with leading zero. | ||
q.e--; | ||
p--; | ||
} | ||
// Round? | ||
if (qi > d) round(q, dp, Big.RM, r[0] !== UNDEFINED); | ||
if (qi > p) round(q, p, Big.RM, r[0] !== UNDEFINED); | ||
@@ -474,3 +459,3 @@ return q; | ||
P.eq = function (y) { | ||
return !this.cmp(y); | ||
return this.cmp(y) === 0; | ||
}; | ||
@@ -629,3 +614,5 @@ | ||
if (!y.c[0]) throw Error(DIV_BY_ZERO); | ||
if (!y.c[0]) { | ||
throw Error(DIV_BY_ZERO); | ||
} | ||
@@ -734,3 +721,6 @@ x.s = y.s = 1; | ||
if (n !== ~~n || n < -MAX_POWER || n > MAX_POWER) throw Error(INVALID + 'exponent'); | ||
if (n !== ~~n || n < -MAX_POWER || n > MAX_POWER) { | ||
throw Error(INVALID + 'exponent'); | ||
} | ||
if (isneg) n = -n; | ||
@@ -750,16 +740,31 @@ | ||
/* | ||
* Return a new Big whose value is the value of this Big rounded using rounding mode rm | ||
* to a maximum of dp decimal places, or, if dp is negative, to an integer which is a | ||
* multiple of 10**-dp. | ||
* Return a new Big whose value is the value of this Big rounded to a maximum precision of sd | ||
* significant digits using rounding mode rm, or Big.RM if rm is not specified. | ||
* | ||
* sd {number} Significant digits: integer, 1 to MAX_DP inclusive. | ||
* rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). | ||
*/ | ||
P.prec = function (sd, rm) { | ||
if (sd !== ~~sd || sd < 1 || sd > MAX_DP) { | ||
throw Error(INVALID + 'precision'); | ||
} | ||
return round(new this.constructor(this), sd, rm); | ||
}; | ||
/* | ||
* Return a new Big whose value is the value of this Big rounded to a maximum of dp decimal places | ||
* using rounding mode rm, or Big.RM if rm is not specified. | ||
* If dp is negative, round to an integer which is a multiple of 10**-dp. | ||
* If dp is not specified, round to 0 decimal places. | ||
* If rm is not specified, use Big.RM. | ||
* | ||
* dp? {number} Integer, -MAX_DP to MAX_DP inclusive. | ||
* rm? 0, 1, 2 or 3 (ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN, ROUND_UP) | ||
* rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). | ||
*/ | ||
P.round = function (dp, rm) { | ||
var Big = this.constructor; | ||
if (dp === UNDEFINED) dp = 0; | ||
else if (dp !== ~~dp || dp < -MAX_DP || dp > MAX_DP) throw Error(INVALID_DP); | ||
return round(new Big(this), dp, rm === UNDEFINED ? Big.RM : rm); | ||
else if (dp !== ~~dp || dp < -MAX_DP || dp > MAX_DP) { | ||
throw Error(INVALID_DP); | ||
} | ||
return round(new this.constructor(this), dp + this.e + 1, rm); | ||
}; | ||
@@ -784,3 +789,5 @@ | ||
// Negative? | ||
if (s < 0) throw Error(NAME + 'No square root'); | ||
if (s < 0) { | ||
throw Error(NAME + 'No square root'); | ||
} | ||
@@ -810,3 +817,3 @@ // Estimate. | ||
return round(r, Big.DP -= 4, Big.RM); | ||
return round(r, (Big.DP -= 4) + r.e + 1, Big.RM); | ||
}; | ||
@@ -868,3 +875,3 @@ | ||
c[j] = (c[j] + b) % 10; | ||
c[j] = b; | ||
} | ||
@@ -885,9 +892,21 @@ | ||
/* | ||
* Return a string representing the value of this Big in exponential notation to dp fixed decimal | ||
* places and rounded using Big.RM. | ||
* Return a string representing the value of this Big in exponential notation rounded to dp fixed | ||
* decimal places using rounding mode rm, or Big.RM if rm is not specified. | ||
* | ||
* dp? {number} Integer, 0 to MAX_DP inclusive. | ||
* dp? {number} Decimal places: integer, 0 to MAX_DP inclusive. | ||
* rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). | ||
*/ | ||
P.toExponential = function (dp) { | ||
return stringify(this, 1, dp, dp); | ||
P.toExponential = function (dp, rm) { | ||
var x = this, | ||
n = x.c[0]; | ||
if (dp !== UNDEFINED) { | ||
if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { | ||
throw Error(INVALID_DP); | ||
} | ||
x = round(new x.constructor(x), ++dp, rm); | ||
for (; x.c.length < dp;) x.c.push(0); | ||
} | ||
return stringify(x, true, !!n); | ||
}; | ||
@@ -897,6 +916,7 @@ | ||
/* | ||
* Return a string representing the value of this Big in normal notation to dp fixed decimal | ||
* places and rounded using Big.RM. | ||
* Return a string representing the value of this Big in normal notation rounded to dp fixed | ||
* decimal places using rounding mode rm, or Big.RM if rm is not specified. | ||
* | ||
* dp? {number} Integer, 0 to MAX_DP inclusive. | ||
* dp? {number} Decimal places: integer, 0 to MAX_DP inclusive. | ||
* rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). | ||
* | ||
@@ -906,4 +926,17 @@ * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. | ||
*/ | ||
P.toFixed = function (dp) { | ||
return stringify(this, 2, dp, this.e + dp); | ||
P.toFixed = function (dp, rm) { | ||
var x = this, | ||
n = x.c[0]; | ||
if (dp !== UNDEFINED) { | ||
if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { | ||
throw Error(INVALID_DP); | ||
} | ||
x = round(new x.constructor(x), dp + x.e + 1, rm); | ||
// x.e may have changed if the value is rounded up. | ||
for (dp = dp + x.e + 1; x.c.length < dp;) x.c.push(0); | ||
} | ||
return stringify(x, false, !!n); | ||
}; | ||
@@ -913,10 +946,45 @@ | ||
/* | ||
* Return a string representing the value of this Big in exponential notation. | ||
* Include the sign for negative zero. | ||
*/ | ||
P.toJSON = function () { | ||
return stringify(this, true, true); | ||
}; | ||
/* | ||
* Return the value of this Big as a primitve number. | ||
*/ | ||
P.toNumber = function () { | ||
var n = Number(stringify(this, true, true)); | ||
if (this.constructor.strict === true && !this.eq(n.toString())) { | ||
throw Error(NAME + 'Imprecise conversion'); | ||
} | ||
return n; | ||
}; | ||
/* | ||
* Return a string representing the value of this Big rounded to sd significant digits using | ||
* Big.RM. Use exponential notation if sd is less than the number of digits necessary to represent | ||
* rounding mode rm, or Big.RM if rm is not specified. | ||
* Use exponential notation if sd is less than the number of digits necessary to represent | ||
* the integer part of the value in normal notation. | ||
* | ||
* sd {number} Integer, 1 to MAX_DP inclusive. | ||
* sd {number} Significant digits: integer, 1 to MAX_DP inclusive. | ||
* rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). | ||
*/ | ||
P.toPrecision = function (sd) { | ||
return stringify(this, 3, sd, sd - 1); | ||
P.toPrecision = function (sd, rm) { | ||
var x = this, | ||
Big = x.constructor, | ||
n = x.c[0]; | ||
if (sd !== UNDEFINED) { | ||
if (sd !== ~~sd || sd < 1 || sd > MAX_DP) { | ||
throw Error(INVALID + 'precision'); | ||
} | ||
x = round(new Big(x), sd, rm); | ||
for (; x.c.length < sd;) x.c.push(0); | ||
} | ||
return stringify(x, sd <= x.e || x.e <= Big.NE || x.e >= Big.PE, !!n); | ||
}; | ||
@@ -932,3 +1000,5 @@ | ||
P.toString = function () { | ||
return stringify(this); | ||
var x = this, | ||
Big = x.constructor; | ||
return stringify(x, x.e <= Big.NE || x.e >= Big.PE, !!x.c[0]); | ||
}; | ||
@@ -943,4 +1013,9 @@ | ||
*/ | ||
P.valueOf = P.toJSON = function () { | ||
return stringify(this, 4); | ||
P.valueOf = function () { | ||
var x = this, | ||
Big = x.constructor; | ||
if (Big.strict === true) { | ||
throw Error(NAME + 'valueOf disallowed'); | ||
} | ||
return stringify(x, x.e <= Big.NE || x.e >= Big.PE, true); | ||
}; | ||
@@ -947,0 +1022,0 @@ |
@@ -0,1 +1,18 @@ | ||
#### 6.0.0 | ||
* 25/09/20 | ||
* Add optional rounding mode parameter to `toExponential`, `toFixed` and `toPrecision`. | ||
* Add a strict mode to disallow imprecise number/Big conversions when `Big.strict = true`. | ||
* Add `toNumber` method. | ||
* Add `prec` method to round a Big to a specified number of significant digits. | ||
* Add version selector to API documentation. | ||
* Change `toJSON` to return exponential format. | ||
* Remove *big.min.js*. | ||
* Remove `Big.version`. | ||
* Rename *doc* folder to *docs* to use it as the Github publishing source. | ||
* Add legacy API documentation to *docs*. | ||
* Add *README* to *perf* directory. | ||
* Refactor test suite, and add `toNumber` and `prec` tests. | ||
* Update *README*. | ||
#### 5.2.2 | ||
@@ -2,0 +19,0 @@ |
{ | ||
"name": "big.js", | ||
"description": "A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic", | ||
"version": "5.2.2", | ||
"version": "6.0.0", | ||
"keywords": [ | ||
@@ -38,14 +38,12 @@ "arbitrary", | ||
"scripts": { | ||
"test": "node ./test/every-test.js", | ||
"build": "uglifyjs big.js --source-map -c -m -o big.min.js" | ||
"test": "node ./test/runner.js" | ||
}, | ||
"files": [ | ||
"big.js", | ||
"big.mjs", | ||
"big.min.js" | ||
"big.mjs" | ||
], | ||
"collective": { | ||
"funding": { | ||
"type": "opencollective", | ||
"url": "https://opencollective.com/bigjs" | ||
} | ||
} | ||
} |
244
README.md
@@ -5,21 +5,26 @@ # big.js | ||
The little sister to [bignumber.js](https://github.com/MikeMcl/bignumber.js/) and [decimal.js](https://github.com/MikeMcl/decimal.js/). See [here](https://github.com/MikeMcl/big.js/wiki) for some notes on the difference between them. | ||
[![npm version](https://img.shields.io/npm/v/big.js.svg)](https://www.npmjs.com/package/big.js) | ||
[![npm downloads](https://img.shields.io/npm/dw/big.js)](https://www.npmjs.com/package/big.js) | ||
## Features | ||
- Faster, smaller and easier-to-use than JavaScript versions of Java's BigDecimal | ||
- Only 5.9 KB minified and 2.7 KB gzipped | ||
- Simple API | ||
- Replicates the `toExponential`, `toFixed` and `toPrecision` methods of JavaScript's Number type | ||
- Includes a `sqrt` method | ||
- Stores values in an accessible decimal floating point format | ||
- No dependencies | ||
- Comprehensive [documentation](http://mikemcl.github.io/big.js/) and test set | ||
- Simple API | ||
- Faster, smaller and easier-to-use than JavaScript versions of Java's BigDecimal | ||
- Only 6 KB minified | ||
- Replicates the `toExponential`, `toFixed` and `toPrecision` methods of JavaScript Numbers | ||
- Stores values in an accessible decimal floating point format | ||
- Comprehensive [documentation](http://mikemcl.github.io/big.js/) and test set | ||
- No dependencies | ||
- Uses ECMAScript 3 only, so works in all browsers | ||
## Set up | ||
The little sister to [bignumber.js](https://github.com/MikeMcl/bignumber.js/) and [decimal.js](https://github.com/MikeMcl/decimal.js/). See [here](https://github.com/MikeMcl/big.js/wiki) for some notes on the difference between them. | ||
The library is the single JavaScript file *big.js* (or *big.min.js*, which is *big.js* minified). | ||
## Install | ||
Browser: | ||
The library is the single JavaScript file *big.js* or the ES module *big.mjs*. | ||
### Browsers | ||
Add Big to global scope: | ||
```html | ||
@@ -29,4 +34,17 @@ <script src='path/to/big.js'></script> | ||
[Node.js](http://nodejs.org): | ||
ES module: | ||
```html | ||
<script type='module'> | ||
import Big from './path/to/big.mjs'; | ||
``` | ||
Get a minified version from a CDN: | ||
```html | ||
<script src='https://cdn.jsdelivr.net/npm/big.js@6.0.0/big.min.js'></script> | ||
``` | ||
### [Node.js](http://nodejs.org) | ||
```bash | ||
@@ -36,2 +54,4 @@ $ npm install big.js | ||
CommonJS: | ||
```javascript | ||
@@ -41,37 +61,63 @@ const Big = require('big.js'); | ||
ES6 module: | ||
ES module: | ||
```javascript | ||
import Big from 'big.mjs'; | ||
import Big from 'big.js'; | ||
``` | ||
### [Deno](https://deno.land/) | ||
```javascript | ||
import Big from 'https://raw.githubusercontent.com/mikemcl/big.js/v6.0.0/big.mjs'; | ||
import Big from 'https://unpkg.com/big.js@6.0.0/big.mjs'; | ||
``` | ||
## Use | ||
*In all examples below, `var`, semicolons and `toString` calls are not shown. If a commented-out value is in quotes it means `toString` has been called on the preceding expression.* | ||
*In the code examples below, semicolons and `toString` calls are not shown.* | ||
The library exports a single function, `Big`, the constructor of Big number instances. | ||
It accepts a value of type number, string or Big number object. | ||
The library exports a single constructor function, `Big`. | ||
x = new Big(123.4567) | ||
y = Big('123456.7e-3') // 'new' is optional | ||
z = new Big(x) | ||
x.eq(y) && x.eq(z) && y.eq(z) // true | ||
A Big number is created from a primitive number, string, or other Big number. | ||
```javascript | ||
x = new Big(123.4567) | ||
y = Big('123456.7e-3') // 'new' is optional | ||
z = new Big(x) | ||
x.eq(y) && x.eq(z) && y.eq(z) // true | ||
``` | ||
In Big strict mode, creating a Big number from a primitive number is disallowed. | ||
```javascript | ||
Big.strict = true | ||
x = new Big(1) // TypeError: [big.js] Invalid number | ||
y = new Big('1.0000000000000001') | ||
y.toNumber() // Error: [big.js] Imprecise conversion | ||
``` | ||
A Big number is immutable in the sense that it is not changed by its methods. | ||
0.3 - 0.1 // 0.19999999999999998 | ||
x = new Big(0.3) | ||
x.minus(0.1) // "0.2" | ||
x // "0.3" | ||
```javascript | ||
0.3 - 0.1 // 0.19999999999999998 | ||
x = new Big(0.3) | ||
x.minus(0.1) // "0.2" | ||
x // "0.3" | ||
``` | ||
The methods that return a Big number can be chained. | ||
x.div(y).plus(z).times(9).minus('1.234567801234567e+8').plus(976.54321).div('2598.11772') | ||
x.sqrt().div(y).pow(3).gt(y.mod(z)) // true | ||
```javascript | ||
x.div(y).plus(z).times(9).minus('1.234567801234567e+8').plus(976.54321).div('2598.11772') | ||
x.sqrt().div(y).pow(3).gt(y.mod(z)) // true | ||
``` | ||
Like JavaScript's Number type, there are `toExponential`, `toFixed` and `toPrecision` methods. | ||
x = new Big(255.5) | ||
x.toExponential(5) // "2.55500e+2" | ||
x.toFixed(5) // "255.50000" | ||
x.toPrecision(5) // "255.50" | ||
```javascript | ||
x = new Big(255.5) | ||
x.toExponential(5) // "2.55500e+2" | ||
x.toFixed(5) // "255.50000" | ||
x.toPrecision(5) // "255.50" | ||
``` | ||
@@ -83,78 +129,62 @@ The arithmetic methods always return the exact result except `div`, `sqrt` and `pow` | ||
Big.DP = 10 | ||
Big.RM = 1 | ||
```javascript | ||
Big.DP = 10 | ||
Big.RM = 1 | ||
x = new Big(2); | ||
y = new Big(3); | ||
z = x.div(y) // "0.6666666667" | ||
z.sqrt() // "0.8164965809" | ||
z.pow(-3) // "3.3749999995" | ||
z.times(z) // "0.44444444448888888889" | ||
z.times(z).round(10) // "0.4444444445" | ||
x = new Big(2); | ||
y = new Big(3); | ||
z = x.div(y) // "0.6666666667" | ||
z.sqrt() // "0.8164965809" | ||
z.pow(-3) // "3.3749999995" | ||
z.times(z) // "0.44444444448888888889" | ||
z.times(z).round(10) // "0.4444444445" | ||
``` | ||
Multiple Big number constructors can be created, each with an independent configuration. | ||
The value of a Big number is stored in a decimal floating point format in terms of a coefficient, exponent and sign. | ||
x = new Big(-123.456); | ||
x.c // [1,2,3,4,5,6] coefficient (i.e. significand) | ||
x.e // 2 exponent | ||
x.s // -1 sign | ||
```javascript | ||
x = new Big(-123.456); | ||
x.c // [1,2,3,4,5,6] coefficient (i.e. significand) | ||
x.e // 2 exponent | ||
x.s // -1 sign | ||
``` | ||
For further information see the [API](http://mikemcl.github.io/big.js/) reference from the *doc* folder. | ||
For advanced usage, multiple Big number constructors can be created, each with an independent configuration. | ||
## Test | ||
For further information see the [API](http://mikemcl.github.io/big.js/) reference documentation. | ||
The *test* directory contains the test scripts for each Big number method. | ||
## Minify | ||
The tests can be run with Node.js or a browser. | ||
To minify using, for example, npm and [terser](https://github.com/terser/terse) | ||
To run all the tests | ||
```bash | ||
$ npm install -g terser | ||
``` | ||
$ npm test | ||
```bash | ||
$ terser big.js -c -m -o big.min.js | ||
``` | ||
To test a single method | ||
## Test | ||
$ node test/toFixed | ||
The *test* directory contains the test scripts for each Big number method. | ||
For the browser, see *single-test.html* and *every-test.html* in the *test/browser* directory. | ||
The tests can be run with Node.js or a browser. | ||
*big-vs-number.html* is a simple application that enables some of the methods of big.js to be compared with those of JavaScript's Number type. | ||
Run all the tests: | ||
## Performance | ||
```bash | ||
$ npm test | ||
``` | ||
The *perf* directory contains two legacy applications and a *lib* directory containing the BigDecimal libraries used by both. | ||
Test a single method: | ||
*big-vs-bigdecimal.html* tests the performance of big.js against the JavaScript translations of two versions of BigDecimal, its use should be more or less self-explanatory. | ||
```bash | ||
$ node test/toFixed | ||
``` | ||
* [GWT: java.math.BigDecimal](https://github.com/iriscouch/bigdecimal.js) | ||
* [ICU4J: com.ibm.icu.math.BigDecimal](https://github.com/dtrebbien/BigDecimal.js) | ||
For the browser, see *runner.html* and *test.html* in the *test/browser* directory. | ||
The BigDecimal in the npm registry is the GWT version. It has some bugs, see the Node.js script *perf/lib/bigdecimal_GWT/bugs.js* for examples of flaws in its *remainder*, *divide* and *compareTo* methods. | ||
*big-vs-number.html* is a old application that enables some of the methods of big.js to be compared with those of JavaScript's Number type. | ||
*bigtime.js* is a Node.js command-line application which tests the performance of big.js against the GWT version of | ||
BigDecimal from the npm registry. | ||
For example, to compare the time taken by the big.js `plus` method and the BigDecimal `add` method | ||
$ node bigtime plus 10000 40 | ||
This will time 10000 calls to each, using operands of up to 40 random digits and will check that the results match. | ||
For help | ||
$ node bigtime -h | ||
## Build | ||
If [uglify-js](https://github.com/mishoo/UglifyJS2) is installed globally | ||
$ npm install uglify-js -g | ||
then | ||
$ npm run build | ||
will create *big.min.js*. | ||
## TypeScript | ||
@@ -164,44 +194,20 @@ | ||
$ npm install @types/big.js | ||
```bash | ||
$ npm install --save-dev @types/big.js | ||
``` | ||
Any questions about the TypeScript type definitions file should be addressed to the DefinitelyTyped project. | ||
## Feedback | ||
Bugs/comments/questions? | ||
Open an issue, or email <a href="mailto:M8ch88l@gmail.com">Michael</a> | ||
## Licence | ||
[MIT](LICENCE) | ||
[MIT](LICENCE.md) | ||
## Contributors | ||
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. | ||
<a href="graphs/contributors"><img src="https://opencollective.com/bigjs/contributors.svg?width=890&button=false" /></a> | ||
## Financial supporters | ||
## Backers | ||
Thank you to all who have supported this project via [Open Collective](https://opencollective.com/bigjs), particularly [Coinbase](https://www.coinbase.com/). | ||
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/bigjs#backer)] | ||
<a href="https://opencollective.com/bigjs#backers" target="_blank"><img src="https://opencollective.com/bigjs/backers.svg?width=890"></a> | ||
## Sponsors | ||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/bigjs#sponsor)] | ||
<a href="https://opencollective.com/bigjs/sponsor/0/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/0/avatar.svg"></a> | ||
<a href="https://opencollective.com/bigjs/sponsor/1/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/1/avatar.svg"></a> | ||
<a href="https://opencollective.com/bigjs/sponsor/2/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/2/avatar.svg"></a> | ||
<a href="https://opencollective.com/bigjs/sponsor/3/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/3/avatar.svg"></a> | ||
<a href="https://opencollective.com/bigjs/sponsor/4/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/4/avatar.svg"></a> | ||
<a href="https://opencollective.com/bigjs/sponsor/5/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/5/avatar.svg"></a> | ||
<a href="https://opencollective.com/bigjs/sponsor/6/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/6/avatar.svg"></a> | ||
<a href="https://opencollective.com/bigjs/sponsor/7/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/7/avatar.svg"></a> | ||
<a href="https://opencollective.com/bigjs/sponsor/8/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/8/avatar.svg"></a> | ||
<a href="https://opencollective.com/bigjs/sponsor/9/website" target="_blank"><img src="https://opencollective.com/bigjs/sponsor/9/avatar.svg"></a> | ||
<img src="https://opencollective.com/bigjs/sponsor/0/avatar.svg"> |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1591
208
61091
6
1