BOC v1.0: RS256 auth, Ledger integration, Prometheus metrics, CI/CD, backup
This commit is contained in:
+87
@@ -0,0 +1,87 @@
|
||||
#### 2.5.1
|
||||
* 30/09/2020
|
||||
* Correct initial `sqrt` estimate.
|
||||
|
||||
#### 2.5.0
|
||||
* 16/10/2018
|
||||
* Add default export to *decimal.d.ts*.
|
||||
* Add `Symbol.for('nodejs.util.inspect.custom')` to *decimal.mjs*.
|
||||
|
||||
#### 2.4.1
|
||||
* 24/05/2018
|
||||
* Add `browser` field to *package.json*.
|
||||
|
||||
#### 2.4.0
|
||||
* 22/05/2018
|
||||
* Amend *.mjs* exports.
|
||||
* Remove extension from `main` field in *package.json*.
|
||||
|
||||
#### 2.3.1
|
||||
* 13/11/2017
|
||||
* Add constructor properties to typings.
|
||||
* Amend `LN10` section of *doc/API.html*.
|
||||
|
||||
#### 2.3.0
|
||||
* 26/09/2017
|
||||
* Add *bignumber.mjs*.
|
||||
|
||||
#### 2.2.5
|
||||
* 08/09/2017
|
||||
* #5 Fix import.
|
||||
|
||||
#### 2.2.4
|
||||
* 15/08/2017
|
||||
* Add TypeScript type declaration file, *decimal.d.ts*
|
||||
* Correct `toPositive` and `toNegative` examples
|
||||
|
||||
#### 2.2.3
|
||||
* 04/05/2017
|
||||
* Fix *README* badge
|
||||
|
||||
#### 2.2.2
|
||||
05/04/2017
|
||||
* `Decimal.default` to `Decimal['default']` IE8 issue
|
||||
|
||||
#### 2.2.1
|
||||
10/03/2017
|
||||
* Remove `tonum` from documentation
|
||||
|
||||
#### 2.2.0
|
||||
10/01/2017
|
||||
* Add `exponent` method
|
||||
|
||||
#### 2.0.2
|
||||
12/12/2016
|
||||
* npm publish
|
||||
|
||||
#### 2.0.1
|
||||
12/12/2016
|
||||
* Filename-casing issue
|
||||
|
||||
#### 2.0.0
|
||||
11/12/2016
|
||||
* Make `LN10` configurable at runtime
|
||||
* Reduce `LN10` default precision
|
||||
* Remove `ceil`, `floor`, `min`, `max` and `truncated`
|
||||
* Rename `divToInt` to `idiv`, `toSD` to `tosd`, `toDP` to `todp`, `isInt` to `isint`, `isNeg` to `isneg`, `isPos` to `ispos` and `round` to `toInteger`
|
||||
* Rename some test files
|
||||
* Add `set` as alias to `config`
|
||||
* Support ES6 import shims
|
||||
* Add to README
|
||||
|
||||
#### 1.0.4
|
||||
28/02/2016
|
||||
* Add to README
|
||||
|
||||
#### 1.0.3
|
||||
25/02/2016
|
||||
* Add to README
|
||||
|
||||
#### 1.0.2
|
||||
25/02/2016
|
||||
* Correct url
|
||||
* Amend .travis.yml as Node.js v0.6 doesn't include `process.hrtime` which is used in testing.
|
||||
|
||||
#### 1.0.0
|
||||
24/02/2016
|
||||
* Initial release
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
The MIT Expat Licence.
|
||||
|
||||
Copyright (c) 2020 Michael Mclaughlin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||

|
||||
|
||||
The light version of [decimal.js](https://github.com/MikeMcl/decimal.js/), an arbitrary-precision Decimal type for JavaScript.
|
||||
|
||||
[](https://travis-ci.org/MikeMcl/decimal.js-light)
|
||||
|
||||
<br />
|
||||
|
||||
This library is the newest of the family of libraries: [bignumber.js](https://github.com/MikeMcl/bignumber.js/), [big.js](https://github.com/MikeMcl/big.js/), [decimal.js](https://github.com/MikeMcl/decimal.js/) and *decimal.js-light*.<br>
|
||||
The API is more or less a subset of the API of *decimal.js*.
|
||||
|
||||

|
||||
|
||||
__Differences between this library and *decimal.js*__
|
||||
|
||||
Size of *decimal.js* minified: 32.1 KB.<br>
|
||||
Size of *decimal.js-light* minified: 12.7 KB.
|
||||
|
||||
This library does not include `NaN`, `Infinity` or `-0` as legitimate values, or work with values in other bases.
|
||||
|
||||
Here, the `Decimal.round` property is just the default rounding mode for `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. It does not apply to arithmetic operations, which are simply truncated at the required precision.
|
||||
|
||||
If rounding is required just apply it explicitly, for example
|
||||
|
||||
```js
|
||||
x = new Decimal(2);
|
||||
y = new Decimal(3);
|
||||
|
||||
// decimal.js
|
||||
x.dividedBy(y).toString(); // '0.66666666666666666667'
|
||||
|
||||
// decimal.js-light
|
||||
x.dividedBy(y).toString(); // '0.66666666666666666666'
|
||||
x.dividedBy(y).toDecimalPlaces(19).toString(); // '0.6666666666666666667'
|
||||
```
|
||||
|
||||
The `naturalExponential`, `naturalLogarithm`, `logarithm`, and `toPower` methods in this library have by default a limited precision of around 100 digits. This limit can be increased at runtime using the `LN10` (the natural logarithm of ten) configuration object property.
|
||||
|
||||
For example, if a maximum precision of 400 digits is required for these operations use
|
||||
|
||||
```js
|
||||
// 415 digits
|
||||
Decimal.set({
|
||||
LN10: '2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286248633409525465082806756666287369098781689482907208325554680843799894826233198528393505308965377732628846163366222287698219886746543667474404243274365155048934314939391479619404400222105101714174800368808401264708068556774321622835522011480466371565912137345074785694768346361679210180644507064800027'
|
||||
});
|
||||
```
|
||||
|
||||
Also, in this library the `e` property of a Decimal is the base 10000000 exponent, not the base 10 exponent as in *decimal.js*.<br>
|
||||
Use the `exponent` method to get the base 10 exponent.
|
||||
|
||||
## Quickstart
|
||||
|
||||
Browser:
|
||||
|
||||
```html
|
||||
<script src='path/to/decimal.js-light'></script>
|
||||
```
|
||||
|
||||
Node package manager:
|
||||
|
||||
```shell
|
||||
$ npm install --save decimal.js-light
|
||||
```
|
||||
|
||||
```js
|
||||
// Node.js
|
||||
var Decimal = require('decimal.js-light');
|
||||
|
||||
// Adjust the global configuration if required (these are the defaults)
|
||||
Decimal.set({
|
||||
precision: 20,
|
||||
rounding: Decimal.ROUND_HALF_UP,
|
||||
toExpNeg: -7,
|
||||
toExpPos: 21
|
||||
});
|
||||
|
||||
phi = new Decimal('1.61803398874989484820458683436563811772030917980576');
|
||||
|
||||
phi.toFixed(10); // '1.6180339887'
|
||||
|
||||
phi.times(2).minus(1).toPower(2).plus('1e-19').equals(5); // true
|
||||
|
||||
```
|
||||
|
||||
See the [documentation](http://mikemcl.github.io/decimal.js-light) for further information.
|
||||
|
||||
[TypeScript](https://github.com/Microsoft/TypeScript) type declaration file contributed by [TANAKA Koichi](https://github.com/MugeSo).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+570
@@ -0,0 +1,570 @@
|
||||
export default Decimal;
|
||||
|
||||
export declare class Decimal {
|
||||
/**
|
||||
* The Decimal constructor and exported function.
|
||||
* Return a new Decimal instance.
|
||||
*
|
||||
* @param value {number|string|Decimal} A numeric value.
|
||||
*
|
||||
*/
|
||||
constructor(value: Numeric)
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the absolute value of this Decimal.
|
||||
*/
|
||||
absoluteValue(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the absolute value of this Decimal.
|
||||
*/
|
||||
abs(): Decimal;
|
||||
|
||||
/**
|
||||
* Return
|
||||
* 1 if the value of this Decimal is greater than the value of `y`,
|
||||
* -1 if the value of this Decimal is less than the value of `y`,
|
||||
* 0 if they have the same value
|
||||
*/
|
||||
comparedTo(y: Numeric): 1|0|-1;
|
||||
|
||||
/**
|
||||
* Return
|
||||
* 1 if the value of this Decimal is greater than the value of `y`,
|
||||
* -1 if the value of this Decimal is less than the value of `y`,
|
||||
* 0 if they have the same value
|
||||
*/
|
||||
cmp(y: Numeric): 1|0|-1;
|
||||
|
||||
/**
|
||||
* Return the number of decimal places of the value of this Decimal.
|
||||
*/
|
||||
decimalPlaces(): number;
|
||||
|
||||
/**
|
||||
* Return the number of decimal places of the value of this Decimal.
|
||||
*/
|
||||
dp(): number;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal divided by `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
dividedBy(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal divided by `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
div(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the integer part of dividing the value of this Decimal
|
||||
* by the value of `y`, truncated to `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
dividedToIntegerBy(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the integer part of dividing the value of this Decimal
|
||||
* by the value of `y`, truncated to `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
idiv(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is equal to the value of `y`, otherwise return false.
|
||||
*/
|
||||
equals(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is equal to the value of `y`, otherwise return false.
|
||||
*/
|
||||
eq(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return the (base 10) exponent value of this Decimal (this.e is the base 10000000 exponent).
|
||||
*/
|
||||
exponent(): number;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is greater than the value of `y`, otherwise return
|
||||
* false.
|
||||
*/
|
||||
greaterThan(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is greater than the value of `y`, otherwise return
|
||||
* false.
|
||||
*/
|
||||
gt(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is greater than or equal to the value of `y`,
|
||||
* otherwise return false.
|
||||
*
|
||||
*/
|
||||
greaterThanOrEqualTo(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is greater than or equal to the value of `y`,
|
||||
* otherwise return false.
|
||||
*
|
||||
*/
|
||||
gte(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is an integer, otherwise return false.
|
||||
*
|
||||
*/
|
||||
isInteger(): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is an integer, otherwise return false.
|
||||
*
|
||||
*/
|
||||
isint(): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is negative, otherwise return false.
|
||||
*
|
||||
*/
|
||||
isNegative(): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is negative, otherwise return false.
|
||||
*
|
||||
*/
|
||||
isneg(): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is positive, otherwise return false.
|
||||
*
|
||||
*/
|
||||
isPositive(): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is positive, otherwise return false.
|
||||
*
|
||||
*/
|
||||
ispos(): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is 0, otherwise return false.
|
||||
*
|
||||
*/
|
||||
isZero(): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is less than `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
lessThan(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is less than `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
lt(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is less than or equal to `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
lessThanOrEqualTo(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the value of this Decimal is less than or equal to `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
lte(y: Numeric): boolean;
|
||||
|
||||
/**
|
||||
* Return the logarithm of the value of this Decimal to the specified base, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
* If no base is specified, return log[10](x).
|
||||
*
|
||||
* log[base](x) = ln(x) / ln(base)
|
||||
*
|
||||
* The maximum error of the result is 1 ulp (unit in the last place).
|
||||
*
|
||||
*/
|
||||
logarithm(base?: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return the logarithm of the value of this Decimal to the specified base, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
* If no base is specified, return log[10](x).
|
||||
*
|
||||
* log[base](x) = ln(x) / ln(base)
|
||||
*
|
||||
* The maximum error of the result is 1 ulp (unit in the last place).
|
||||
*
|
||||
*/
|
||||
log(base?: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal minus `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
minus(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal minus `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
sub(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal modulo `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
modulo(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal modulo `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
mod(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the natural exponential of the value of this Decimal,
|
||||
* i.e. the base e raised to the power the value of this Decimal, truncated to `precision`
|
||||
* significant digits.
|
||||
*
|
||||
*/
|
||||
naturalExponetial(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the natural exponential of the value of this Decimal,
|
||||
* i.e. the base e raised to the power the value of this Decimal, truncated to `precision`
|
||||
* significant digits.
|
||||
*
|
||||
*/
|
||||
exp(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the natural logarithm of the value of this Decimal,
|
||||
* truncated to `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
naturalLogarithm(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the natural logarithm of the value of this Decimal,
|
||||
* truncated to `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
ln(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by
|
||||
* -1.
|
||||
*
|
||||
*/
|
||||
negated(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by
|
||||
* -1.
|
||||
*
|
||||
*/
|
||||
neg(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal plus `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
plus(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal plus `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
add(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return the number of significant digits of the value of this Decimal.
|
||||
*
|
||||
* @param zeros {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0.
|
||||
*/
|
||||
precision(zeros: boolean|number): number;
|
||||
|
||||
/**
|
||||
* Return the number of significant digits of the value of this Decimal.
|
||||
*
|
||||
* @param zeros {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0.
|
||||
*/
|
||||
sd(zeros: boolean|number): number;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the square root of this Decimal, truncated to `precision`
|
||||
* significant digits.
|
||||
*
|
||||
*/
|
||||
squareRoot(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the square root of this Decimal, truncated to `precision`
|
||||
* significant digits.
|
||||
*
|
||||
*/
|
||||
sqrt(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal times `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
times(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal times `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
mul(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp`
|
||||
* decimal places using rounding mode `rm` or `rounding` if `rm` is omitted.
|
||||
*
|
||||
* If `dp` is omitted, return a new Decimal whose value is the value of this Decimal.
|
||||
*
|
||||
* @param dp {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* @param rm {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
toDecimalPlaces(dp?: number, rm?: number): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp`
|
||||
* decimal places using rounding mode `rm` or `rounding` if `rm` is omitted.
|
||||
*
|
||||
* If `dp` is omitted, return a new Decimal whose value is the value of this Decimal.
|
||||
*
|
||||
* @param dp {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* @param rm {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
todp(dp?: number, rm?: number): Decimal;
|
||||
|
||||
/**
|
||||
* Return a string representing the value of this Decimal in exponential notation rounded to
|
||||
* `dp` fixed decimal places using rounding mode `rounding`.
|
||||
*
|
||||
* @param dp {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* @param rm {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
toExponential(dp?: number, rm?: number): string;
|
||||
|
||||
/**
|
||||
* Return a string representing the value of this Decimal in normal (fixed-point) notation to
|
||||
* `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is
|
||||
* omitted.
|
||||
*
|
||||
* As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'.
|
||||
*
|
||||
* @param dp {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* @param rm {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
* (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'.
|
||||
* (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'.
|
||||
* (-0).toFixed(3) is '0.000'.
|
||||
* (-0.5).toFixed(0) is '-0'.
|
||||
*
|
||||
*/
|
||||
toFixed(dp?: number, rm?: number): string;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a whole number using
|
||||
* rounding mode `rounding`.
|
||||
*
|
||||
*/
|
||||
toInteger(): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a whole number using
|
||||
* rounding mode `rounding`.
|
||||
*
|
||||
*/
|
||||
toint(): Decimal;
|
||||
|
||||
/**
|
||||
* Return the value of this Decimal converted to a number primitive.
|
||||
*
|
||||
*/
|
||||
toNumber(): number;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal raised to the power `y`,
|
||||
* truncated to `precision` significant digits.
|
||||
*
|
||||
* For non-integer or very large exponents pow(x, y) is calculated using
|
||||
*
|
||||
* x^y = exp(y*ln(x))
|
||||
*
|
||||
* The maximum error is 1 ulp (unit in last place).
|
||||
*
|
||||
* @param y {number|string|Decimal} The power to which to raise this Decimal.
|
||||
*
|
||||
*/
|
||||
toPower(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal raised to the power `y`,
|
||||
* truncated to `precision` significant digits.
|
||||
*
|
||||
* For non-integer or very large exponents pow(x, y) is calculated using
|
||||
*
|
||||
* x^y = exp(y*ln(x))
|
||||
*
|
||||
* The maximum error is 1 ulp (unit in last place).
|
||||
*
|
||||
* @param y {number|string|Decimal} The power to which to raise this Decimal.
|
||||
*
|
||||
*/
|
||||
pow(y: Numeric): Decimal;
|
||||
|
||||
/**
|
||||
* Return a string representing the value of this Decimal rounded to `sd` significant digits
|
||||
* using rounding mode `rounding`.
|
||||
*
|
||||
* Return exponential notation if `sd` is less than the number of digits necessary to represent
|
||||
* the integer part of the value in normal notation.
|
||||
*
|
||||
* @param sd {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
||||
* @param rm {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
toPrecision(sd?: number, rm?: number): string;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd`
|
||||
* significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if
|
||||
* omitted.
|
||||
*
|
||||
* @param sd {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
||||
* @param rm {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
toSignificantDigits(sd?: number, rm?: number): Decimal;
|
||||
|
||||
/**
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd`
|
||||
* significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if
|
||||
* omitted.
|
||||
*
|
||||
* @param sd {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
||||
* @param rm {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
tosd(sd?: number, rm?: number): Decimal;
|
||||
|
||||
/**
|
||||
* Return a string representing the value of this Decimal.
|
||||
*
|
||||
* Return exponential notation if this Decimal has a positive exponent equal to or greater than
|
||||
* `toExpPos`, or a negative exponent equal to or less than `toExpNeg`.
|
||||
*
|
||||
*/
|
||||
toString(): string;
|
||||
|
||||
/**
|
||||
* Return a string representing the value of this Decimal.
|
||||
*
|
||||
* Return exponential notation if this Decimal has a positive exponent equal to or greater than
|
||||
* `toExpPos`, or a negative exponent equal to or less than `toExpNeg`.
|
||||
*
|
||||
*/
|
||||
valueOf(): string;
|
||||
|
||||
/**
|
||||
* Return a string representing the value of this Decimal.
|
||||
*
|
||||
* Return exponential notation if this Decimal has a positive exponent equal to or greater than
|
||||
* `toExpPos`, or a negative exponent equal to or less than `toExpNeg`.
|
||||
*
|
||||
*/
|
||||
val(): string;
|
||||
|
||||
/**
|
||||
* Return a string representing the value of this Decimal.
|
||||
*
|
||||
* Return exponential notation if this Decimal has a positive exponent equal to or greater than
|
||||
* `toExpPos`, or a negative exponent equal to or less than `toExpNeg`.
|
||||
*
|
||||
*/
|
||||
toJSON(): string;
|
||||
|
||||
/**
|
||||
* Create and return a Decimal constructor with the same configuration properties as this Decimal
|
||||
* constructor.
|
||||
*
|
||||
* @param config? Config
|
||||
*/
|
||||
static clone(config?: Config): typeof Decimal;
|
||||
|
||||
/**
|
||||
* Configure global settings for a Decimal constructor.
|
||||
*/
|
||||
static config(config: Config): Decimal;
|
||||
|
||||
/**
|
||||
* Configure global settings for a Decimal constructor.
|
||||
*/
|
||||
static set(config: Config): Decimal;
|
||||
|
||||
// The maximum number of significant digits of the result of a calculation or base conversion.
|
||||
// E.g. `Decimal.config({ precision: 20 });`
|
||||
static precision: number;
|
||||
|
||||
// The rounding mode used by default by `toInteger`, `toDecimalPlaces`, `toExponential`,
|
||||
// `toFixed`, `toPrecision` and `toSignificantDigits`.
|
||||
//
|
||||
// E.g.
|
||||
// `Decimal.rounding = 4;`
|
||||
// `Decimal.rounding = Decimal.ROUND_HALF_UP;`
|
||||
static rounding: number;
|
||||
static readonly ROUND_UP: number;
|
||||
static readonly ROUND_DOWN: number;
|
||||
static readonly ROUND_CEIL: number;
|
||||
static readonly ROUND_FLOOR: number;
|
||||
static readonly ROUND_HALF_UP: number;
|
||||
static readonly ROUND_HALF_DOWN: number;
|
||||
static readonly ROUND_HALF_EVEN: number;
|
||||
static readonly ROUND_HALF_CEIL: number;
|
||||
static readonly ROUND_HALF_FLOOR: number;
|
||||
|
||||
// The exponent value at and beneath which `toString` returns exponential notation.
|
||||
// JavaScript numbers: -7
|
||||
static toExpNeg: number; // 0 to -MAX_E
|
||||
|
||||
// The exponent value at and above which `toString` returns exponential notation.
|
||||
// JavaScript numbers: 21
|
||||
static toExpPos: number; // 0 to MAX_E
|
||||
|
||||
// The natural logarithm of 10.
|
||||
static LN10: Decimal;
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
precision?: number;
|
||||
rounding?: number;
|
||||
toExpNeg?: number;
|
||||
toExpPos?: number;
|
||||
LN10?: Numeric;
|
||||
}
|
||||
|
||||
export type Numeric = string|number|Decimal;
|
||||
+2014
@@ -0,0 +1,2014 @@
|
||||
/*! decimal.js-light v2.5.1 https://github.com/MikeMcl/decimal.js-light/LICENCE */
|
||||
;(function (globalScope) {
|
||||
'use strict';
|
||||
|
||||
|
||||
/*
|
||||
* decimal.js-light v2.5.1
|
||||
* An arbitrary-precision Decimal type for JavaScript.
|
||||
* https://github.com/MikeMcl/decimal.js-light
|
||||
* Copyright (c) 2020 Michael Mclaughlin <M8ch88l@gmail.com>
|
||||
* MIT Expat Licence
|
||||
*/
|
||||
|
||||
|
||||
// ----------------------------------- EDITABLE DEFAULTS ------------------------------------ //
|
||||
|
||||
|
||||
// The limit on the value of `precision`, and on the value of the first argument to
|
||||
// `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`.
|
||||
var MAX_DIGITS = 1e9, // 0 to 1e9
|
||||
|
||||
|
||||
// The initial configuration properties of the Decimal constructor.
|
||||
Decimal = {
|
||||
|
||||
// These values must be integers within the stated ranges (inclusive).
|
||||
// Most of these values can be changed during run-time using `Decimal.config`.
|
||||
|
||||
// The maximum number of significant digits of the result of a calculation or base conversion.
|
||||
// E.g. `Decimal.config({ precision: 20 });`
|
||||
precision: 20, // 1 to MAX_DIGITS
|
||||
|
||||
// The rounding mode used by default by `toInteger`, `toDecimalPlaces`, `toExponential`,
|
||||
// `toFixed`, `toPrecision` and `toSignificantDigits`.
|
||||
//
|
||||
// ROUND_UP 0 Away from zero.
|
||||
// ROUND_DOWN 1 Towards zero.
|
||||
// ROUND_CEIL 2 Towards +Infinity.
|
||||
// ROUND_FLOOR 3 Towards -Infinity.
|
||||
// ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up.
|
||||
// ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down.
|
||||
// ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour.
|
||||
// ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity.
|
||||
// ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
|
||||
//
|
||||
// E.g.
|
||||
// `Decimal.rounding = 4;`
|
||||
// `Decimal.rounding = Decimal.ROUND_HALF_UP;`
|
||||
rounding: 4, // 0 to 8
|
||||
|
||||
// The exponent value at and beneath which `toString` returns exponential notation.
|
||||
// JavaScript numbers: -7
|
||||
toExpNeg: -7, // 0 to -MAX_E
|
||||
|
||||
// The exponent value at and above which `toString` returns exponential notation.
|
||||
// JavaScript numbers: 21
|
||||
toExpPos: 21, // 0 to MAX_E
|
||||
|
||||
// The natural logarithm of 10.
|
||||
// 115 digits
|
||||
LN10: '2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286'
|
||||
},
|
||||
|
||||
|
||||
// ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- //
|
||||
|
||||
|
||||
external = true,
|
||||
|
||||
decimalError = '[DecimalError] ',
|
||||
invalidArgument = decimalError + 'Invalid argument: ',
|
||||
exponentOutOfRange = decimalError + 'Exponent out of range: ',
|
||||
|
||||
mathfloor = Math.floor,
|
||||
mathpow = Math.pow,
|
||||
|
||||
isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
|
||||
|
||||
ONE,
|
||||
BASE = 1e7,
|
||||
LOG_BASE = 7,
|
||||
MAX_SAFE_INTEGER = 9007199254740991,
|
||||
MAX_E = mathfloor(MAX_SAFE_INTEGER / LOG_BASE), // 1286742750677284
|
||||
|
||||
// Decimal.prototype object
|
||||
P = {};
|
||||
|
||||
|
||||
// Decimal prototype methods
|
||||
|
||||
|
||||
/*
|
||||
* absoluteValue abs
|
||||
* comparedTo cmp
|
||||
* decimalPlaces dp
|
||||
* dividedBy div
|
||||
* dividedToIntegerBy idiv
|
||||
* equals eq
|
||||
* exponent
|
||||
* greaterThan gt
|
||||
* greaterThanOrEqualTo gte
|
||||
* isInteger isint
|
||||
* isNegative isneg
|
||||
* isPositive ispos
|
||||
* isZero
|
||||
* lessThan lt
|
||||
* lessThanOrEqualTo lte
|
||||
* logarithm log
|
||||
* minus sub
|
||||
* modulo mod
|
||||
* naturalExponential exp
|
||||
* naturalLogarithm ln
|
||||
* negated neg
|
||||
* plus add
|
||||
* precision sd
|
||||
* squareRoot sqrt
|
||||
* times mul
|
||||
* toDecimalPlaces todp
|
||||
* toExponential
|
||||
* toFixed
|
||||
* toInteger toint
|
||||
* toNumber
|
||||
* toPower pow
|
||||
* toPrecision
|
||||
* toSignificantDigits tosd
|
||||
* toString
|
||||
* valueOf val
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the absolute value of this Decimal.
|
||||
*
|
||||
*/
|
||||
P.absoluteValue = P.abs = function () {
|
||||
var x = new this.constructor(this);
|
||||
if (x.s) x.s = 1;
|
||||
return x;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return
|
||||
* 1 if the value of this Decimal is greater than the value of `y`,
|
||||
* -1 if the value of this Decimal is less than the value of `y`,
|
||||
* 0 if they have the same value
|
||||
*
|
||||
*/
|
||||
P.comparedTo = P.cmp = function (y) {
|
||||
var i, j, xdL, ydL,
|
||||
x = this;
|
||||
|
||||
y = new x.constructor(y);
|
||||
|
||||
// Signs differ?
|
||||
if (x.s !== y.s) return x.s || -y.s;
|
||||
|
||||
// Compare exponents.
|
||||
if (x.e !== y.e) return x.e > y.e ^ x.s < 0 ? 1 : -1;
|
||||
|
||||
xdL = x.d.length;
|
||||
ydL = y.d.length;
|
||||
|
||||
// Compare digit by digit.
|
||||
for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) {
|
||||
if (x.d[i] !== y.d[i]) return x.d[i] > y.d[i] ^ x.s < 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
// Compare lengths.
|
||||
return xdL === ydL ? 0 : xdL > ydL ^ x.s < 0 ? 1 : -1;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of decimal places of the value of this Decimal.
|
||||
*
|
||||
*/
|
||||
P.decimalPlaces = P.dp = function () {
|
||||
var x = this,
|
||||
w = x.d.length - 1,
|
||||
dp = (w - x.e) * LOG_BASE;
|
||||
|
||||
// Subtract the number of trailing zeros of the last word.
|
||||
w = x.d[w];
|
||||
if (w) for (; w % 10 == 0; w /= 10) dp--;
|
||||
|
||||
return dp < 0 ? 0 : dp;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal divided by `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.dividedBy = P.div = function (y) {
|
||||
return divide(this, new this.constructor(y));
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the integer part of dividing the value of this Decimal
|
||||
* by the value of `y`, truncated to `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.dividedToIntegerBy = P.idiv = function (y) {
|
||||
var x = this,
|
||||
Ctor = x.constructor;
|
||||
return round(divide(x, new Ctor(y), 0, 1), Ctor.precision);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is equal to the value of `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.equals = P.eq = function (y) {
|
||||
return !this.cmp(y);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the (base 10) exponent value of this Decimal (this.e is the base 10000000 exponent).
|
||||
*
|
||||
*/
|
||||
P.exponent = function () {
|
||||
return getBase10Exponent(this);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is greater than the value of `y`, otherwise return
|
||||
* false.
|
||||
*
|
||||
*/
|
||||
P.greaterThan = P.gt = function (y) {
|
||||
return this.cmp(y) > 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is greater than or equal to the value of `y`,
|
||||
* otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.greaterThanOrEqualTo = P.gte = function (y) {
|
||||
return this.cmp(y) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is an integer, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.isInteger = P.isint = function () {
|
||||
return this.e > this.d.length - 2;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is negative, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.isNegative = P.isneg = function () {
|
||||
return this.s < 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is positive, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.isPositive = P.ispos = function () {
|
||||
return this.s > 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is 0, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.isZero = function () {
|
||||
return this.s === 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is less than `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.lessThan = P.lt = function (y) {
|
||||
return this.cmp(y) < 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is less than or equal to `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.lessThanOrEqualTo = P.lte = function (y) {
|
||||
return this.cmp(y) < 1;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the logarithm of the value of this Decimal to the specified base, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
* If no base is specified, return log[10](x).
|
||||
*
|
||||
* log[base](x) = ln(x) / ln(base)
|
||||
*
|
||||
* The maximum error of the result is 1 ulp (unit in the last place).
|
||||
*
|
||||
* [base] {number|string|Decimal} The base of the logarithm.
|
||||
*
|
||||
*/
|
||||
P.logarithm = P.log = function (base) {
|
||||
var r,
|
||||
x = this,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision,
|
||||
wpr = pr + 5;
|
||||
|
||||
// Default base is 10.
|
||||
if (base === void 0) {
|
||||
base = new Ctor(10);
|
||||
} else {
|
||||
base = new Ctor(base);
|
||||
|
||||
// log[-b](x) = NaN
|
||||
// log[0](x) = NaN
|
||||
// log[1](x) = NaN
|
||||
if (base.s < 1 || base.eq(ONE)) throw Error(decimalError + 'NaN');
|
||||
}
|
||||
|
||||
// log[b](-x) = NaN
|
||||
// log[b](0) = -Infinity
|
||||
if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity'));
|
||||
|
||||
// log[b](1) = 0
|
||||
if (x.eq(ONE)) return new Ctor(0);
|
||||
|
||||
external = false;
|
||||
r = divide(ln(x, wpr), ln(base, wpr), wpr);
|
||||
external = true;
|
||||
|
||||
return round(r, pr);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal minus `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.minus = P.sub = function (y) {
|
||||
var x = this;
|
||||
y = new x.constructor(y);
|
||||
return x.s == y.s ? subtract(x, y) : add(x, (y.s = -y.s, y));
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal modulo `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.modulo = P.mod = function (y) {
|
||||
var q,
|
||||
x = this,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
y = new Ctor(y);
|
||||
|
||||
// x % 0 = NaN
|
||||
if (!y.s) throw Error(decimalError + 'NaN');
|
||||
|
||||
// Return x if x is 0.
|
||||
if (!x.s) return round(new Ctor(x), pr);
|
||||
|
||||
// Prevent rounding of intermediate calculations.
|
||||
external = false;
|
||||
q = divide(x, y, 0, 1).times(y);
|
||||
external = true;
|
||||
|
||||
return x.minus(q);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the natural exponential of the value of this Decimal,
|
||||
* i.e. the base e raised to the power the value of this Decimal, truncated to `precision`
|
||||
* significant digits.
|
||||
*
|
||||
*/
|
||||
P.naturalExponential = P.exp = function () {
|
||||
return exp(this);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the natural logarithm of the value of this Decimal,
|
||||
* truncated to `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.naturalLogarithm = P.ln = function () {
|
||||
return ln(this);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by
|
||||
* -1.
|
||||
*
|
||||
*/
|
||||
P.negated = P.neg = function () {
|
||||
var x = new this.constructor(this);
|
||||
x.s = -x.s || 0;
|
||||
return x;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal plus `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.plus = P.add = function (y) {
|
||||
var x = this;
|
||||
y = new x.constructor(y);
|
||||
return x.s == y.s ? add(x, y) : subtract(x, (y.s = -y.s, y));
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of significant digits of the value of this Decimal.
|
||||
*
|
||||
* [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0.
|
||||
*
|
||||
*/
|
||||
P.precision = P.sd = function (z) {
|
||||
var e, sd, w,
|
||||
x = this;
|
||||
|
||||
if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z);
|
||||
|
||||
e = getBase10Exponent(x) + 1;
|
||||
w = x.d.length - 1;
|
||||
sd = w * LOG_BASE + 1;
|
||||
w = x.d[w];
|
||||
|
||||
// If non-zero...
|
||||
if (w) {
|
||||
|
||||
// Subtract the number of trailing zeros of the last word.
|
||||
for (; w % 10 == 0; w /= 10) sd--;
|
||||
|
||||
// Add the number of digits of the first word.
|
||||
for (w = x.d[0]; w >= 10; w /= 10) sd++;
|
||||
}
|
||||
|
||||
return z && e > sd ? e : sd;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the square root of this Decimal, truncated to `precision`
|
||||
* significant digits.
|
||||
*
|
||||
*/
|
||||
P.squareRoot = P.sqrt = function () {
|
||||
var e, n, pr, r, s, t, wpr,
|
||||
x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
// Negative or zero?
|
||||
if (x.s < 1) {
|
||||
if (!x.s) return new Ctor(0);
|
||||
|
||||
// sqrt(-x) = NaN
|
||||
throw Error(decimalError + 'NaN');
|
||||
}
|
||||
|
||||
e = getBase10Exponent(x);
|
||||
external = false;
|
||||
|
||||
// Initial estimate.
|
||||
s = Math.sqrt(+x);
|
||||
|
||||
// Math.sqrt underflow/overflow?
|
||||
// Pass x to Math.sqrt as integer, then adjust the exponent of the result.
|
||||
if (s == 0 || s == 1 / 0) {
|
||||
n = digitsToString(x.d);
|
||||
if ((n.length + e) % 2 == 0) n += '0';
|
||||
s = Math.sqrt(n);
|
||||
e = mathfloor((e + 1) / 2) - (e < 0 || e % 2);
|
||||
|
||||
if (s == 1 / 0) {
|
||||
n = '5e' + e;
|
||||
} else {
|
||||
n = s.toExponential();
|
||||
n = n.slice(0, n.indexOf('e') + 1) + e;
|
||||
}
|
||||
|
||||
r = new Ctor(n);
|
||||
} else {
|
||||
r = new Ctor(s.toString());
|
||||
}
|
||||
|
||||
pr = Ctor.precision;
|
||||
s = wpr = pr + 3;
|
||||
|
||||
// Newton-Raphson iteration.
|
||||
for (;;) {
|
||||
t = r;
|
||||
r = t.plus(divide(x, t, wpr + 2)).times(0.5);
|
||||
|
||||
if (digitsToString(t.d).slice(0, wpr) === (n = digitsToString(r.d)).slice(0, wpr)) {
|
||||
n = n.slice(wpr - 3, wpr + 1);
|
||||
|
||||
// The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or
|
||||
// 4999, i.e. approaching a rounding boundary, continue the iteration.
|
||||
if (s == wpr && n == '4999') {
|
||||
|
||||
// On the first iteration only, check to see if rounding up gives the exact result as the
|
||||
// nines may infinitely repeat.
|
||||
round(t, pr + 1, 0);
|
||||
|
||||
if (t.times(t).eq(x)) {
|
||||
r = t;
|
||||
break;
|
||||
}
|
||||
} else if (n != '9999') {
|
||||
break;
|
||||
}
|
||||
|
||||
wpr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
external = true;
|
||||
|
||||
return round(r, pr);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal times `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.times = P.mul = function (y) {
|
||||
var carry, e, i, k, r, rL, t, xdL, ydL,
|
||||
x = this,
|
||||
Ctor = x.constructor,
|
||||
xd = x.d,
|
||||
yd = (y = new Ctor(y)).d;
|
||||
|
||||
// Return 0 if either is 0.
|
||||
if (!x.s || !y.s) return new Ctor(0);
|
||||
|
||||
y.s *= x.s;
|
||||
e = x.e + y.e;
|
||||
xdL = xd.length;
|
||||
ydL = yd.length;
|
||||
|
||||
// Ensure xd points to the longer array.
|
||||
if (xdL < ydL) {
|
||||
r = xd;
|
||||
xd = yd;
|
||||
yd = r;
|
||||
rL = xdL;
|
||||
xdL = ydL;
|
||||
ydL = rL;
|
||||
}
|
||||
|
||||
// Initialise the result array with zeros.
|
||||
r = [];
|
||||
rL = xdL + ydL;
|
||||
for (i = rL; i--;) r.push(0);
|
||||
|
||||
// Multiply!
|
||||
for (i = ydL; --i >= 0;) {
|
||||
carry = 0;
|
||||
for (k = xdL + i; k > i;) {
|
||||
t = r[k] + yd[i] * xd[k - i - 1] + carry;
|
||||
r[k--] = t % BASE | 0;
|
||||
carry = t / BASE | 0;
|
||||
}
|
||||
|
||||
r[k] = (r[k] + carry) % BASE | 0;
|
||||
}
|
||||
|
||||
// Remove trailing zeros.
|
||||
for (; !r[--rL];) r.pop();
|
||||
|
||||
if (carry) ++e;
|
||||
else r.shift();
|
||||
|
||||
y.d = r;
|
||||
y.e = e;
|
||||
|
||||
return external ? round(y, Ctor.precision) : y;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp`
|
||||
* decimal places using rounding mode `rm` or `rounding` if `rm` is omitted.
|
||||
*
|
||||
* If `dp` is omitted, return a new Decimal whose value is the value of this Decimal.
|
||||
*
|
||||
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
P.toDecimalPlaces = P.todp = function (dp, rm) {
|
||||
var x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
x = new Ctor(x);
|
||||
if (dp === void 0) return x;
|
||||
|
||||
checkInt32(dp, 0, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
|
||||
return round(x, dp + getBase10Exponent(x) + 1, rm);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a string representing the value of this Decimal in exponential notation rounded to
|
||||
* `dp` fixed decimal places using rounding mode `rounding`.
|
||||
*
|
||||
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
P.toExponential = function (dp, rm) {
|
||||
var str,
|
||||
x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
if (dp === void 0) {
|
||||
str = toString(x, true);
|
||||
} else {
|
||||
checkInt32(dp, 0, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
|
||||
x = round(new Ctor(x), dp + 1, rm);
|
||||
str = toString(x, true, dp + 1);
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a string representing the value of this Decimal in normal (fixed-point) notation to
|
||||
* `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is
|
||||
* omitted.
|
||||
*
|
||||
* As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'.
|
||||
*
|
||||
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
* (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'.
|
||||
* (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'.
|
||||
* (-0).toFixed(3) is '0.000'.
|
||||
* (-0.5).toFixed(0) is '-0'.
|
||||
*
|
||||
*/
|
||||
P.toFixed = function (dp, rm) {
|
||||
var str, y,
|
||||
x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
if (dp === void 0) return toString(x);
|
||||
|
||||
checkInt32(dp, 0, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
|
||||
y = round(new Ctor(x), dp + getBase10Exponent(x) + 1, rm);
|
||||
str = toString(y.abs(), false, dp + getBase10Exponent(y) + 1);
|
||||
|
||||
// To determine whether to add the minus sign look at the value before it was rounded,
|
||||
// i.e. look at `x` rather than `y`.
|
||||
return x.isneg() && !x.isZero() ? '-' + str : str;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a whole number using
|
||||
* rounding mode `rounding`.
|
||||
*
|
||||
*/
|
||||
P.toInteger = P.toint = function () {
|
||||
var x = this,
|
||||
Ctor = x.constructor;
|
||||
return round(new Ctor(x), getBase10Exponent(x) + 1, Ctor.rounding);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the value of this Decimal converted to a number primitive.
|
||||
*
|
||||
*/
|
||||
P.toNumber = function () {
|
||||
return +this;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal raised to the power `y`,
|
||||
* truncated to `precision` significant digits.
|
||||
*
|
||||
* For non-integer or very large exponents pow(x, y) is calculated using
|
||||
*
|
||||
* x^y = exp(y*ln(x))
|
||||
*
|
||||
* The maximum error is 1 ulp (unit in last place).
|
||||
*
|
||||
* y {number|string|Decimal} The power to which to raise this Decimal.
|
||||
*
|
||||
*/
|
||||
P.toPower = P.pow = function (y) {
|
||||
var e, k, pr, r, sign, yIsInt,
|
||||
x = this,
|
||||
Ctor = x.constructor,
|
||||
guard = 12,
|
||||
yn = +(y = new Ctor(y));
|
||||
|
||||
// pow(x, 0) = 1
|
||||
if (!y.s) return new Ctor(ONE);
|
||||
|
||||
x = new Ctor(x);
|
||||
|
||||
// pow(0, y > 0) = 0
|
||||
// pow(0, y < 0) = Infinity
|
||||
if (!x.s) {
|
||||
if (y.s < 1) throw Error(decimalError + 'Infinity');
|
||||
return x;
|
||||
}
|
||||
|
||||
// pow(1, y) = 1
|
||||
if (x.eq(ONE)) return x;
|
||||
|
||||
pr = Ctor.precision;
|
||||
|
||||
// pow(x, 1) = x
|
||||
if (y.eq(ONE)) return round(x, pr);
|
||||
|
||||
e = y.e;
|
||||
k = y.d.length - 1;
|
||||
yIsInt = e >= k;
|
||||
sign = x.s;
|
||||
|
||||
if (!yIsInt) {
|
||||
|
||||
// pow(x < 0, y non-integer) = NaN
|
||||
if (sign < 0) throw Error(decimalError + 'NaN');
|
||||
|
||||
// If y is a small integer use the 'exponentiation by squaring' algorithm.
|
||||
} else if ((k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) {
|
||||
r = new Ctor(ONE);
|
||||
|
||||
// Max k of 9007199254740991 takes 53 loop iterations.
|
||||
// Maximum digits array length; leaves [28, 34] guard digits.
|
||||
e = Math.ceil(pr / LOG_BASE + 4);
|
||||
|
||||
external = false;
|
||||
|
||||
for (;;) {
|
||||
if (k % 2) {
|
||||
r = r.times(x);
|
||||
truncate(r.d, e);
|
||||
}
|
||||
|
||||
k = mathfloor(k / 2);
|
||||
if (k === 0) break;
|
||||
|
||||
x = x.times(x);
|
||||
truncate(x.d, e);
|
||||
}
|
||||
|
||||
external = true;
|
||||
|
||||
return y.s < 0 ? new Ctor(ONE).div(r) : round(r, pr);
|
||||
}
|
||||
|
||||
// Result is negative if x is negative and the last digit of integer y is odd.
|
||||
sign = sign < 0 && y.d[Math.max(e, k)] & 1 ? -1 : 1;
|
||||
|
||||
x.s = 1;
|
||||
external = false;
|
||||
r = y.times(ln(x, pr + guard));
|
||||
external = true;
|
||||
r = exp(r);
|
||||
r.s = sign;
|
||||
|
||||
return r;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a string representing the value of this Decimal rounded to `sd` significant digits
|
||||
* using rounding mode `rounding`.
|
||||
*
|
||||
* Return 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} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
P.toPrecision = function (sd, rm) {
|
||||
var e, str,
|
||||
x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
if (sd === void 0) {
|
||||
e = getBase10Exponent(x);
|
||||
str = toString(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos);
|
||||
} else {
|
||||
checkInt32(sd, 1, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
|
||||
x = round(new Ctor(x), sd, rm);
|
||||
e = getBase10Exponent(x);
|
||||
str = toString(x, sd <= e || e <= Ctor.toExpNeg, sd);
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd`
|
||||
* significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if
|
||||
* omitted.
|
||||
*
|
||||
* [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
P.toSignificantDigits = P.tosd = function (sd, rm) {
|
||||
var x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
if (sd === void 0) {
|
||||
sd = Ctor.precision;
|
||||
rm = Ctor.rounding;
|
||||
} else {
|
||||
checkInt32(sd, 1, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
}
|
||||
|
||||
return round(new Ctor(x), sd, rm);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a string representing the value of this Decimal.
|
||||
*
|
||||
* Return exponential notation if this Decimal has a positive exponent equal to or greater than
|
||||
* `toExpPos`, or a negative exponent equal to or less than `toExpNeg`.
|
||||
*
|
||||
*/
|
||||
P.toString = P.valueOf = P.val = P.toJSON = function () {
|
||||
var x = this,
|
||||
e = getBase10Exponent(x),
|
||||
Ctor = x.constructor;
|
||||
|
||||
return toString(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos);
|
||||
};
|
||||
|
||||
|
||||
// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers.
|
||||
|
||||
|
||||
/*
|
||||
* add P.minus, P.plus
|
||||
* checkInt32 P.todp, P.toExponential, P.toFixed, P.toPrecision, P.tosd
|
||||
* digitsToString P.log, P.sqrt, P.pow, toString, exp, ln
|
||||
* divide P.div, P.idiv, P.log, P.mod, P.sqrt, exp, ln
|
||||
* exp P.exp, P.pow
|
||||
* getBase10Exponent P.exponent, P.sd, P.toint, P.sqrt, P.todp, P.toFixed, P.toPrecision,
|
||||
* P.toString, divide, round, toString, exp, ln
|
||||
* getLn10 P.log, ln
|
||||
* getZeroString digitsToString, toString
|
||||
* ln P.log, P.ln, P.pow, exp
|
||||
* parseDecimal Decimal
|
||||
* round P.abs, P.idiv, P.log, P.minus, P.mod, P.neg, P.plus, P.toint, P.sqrt,
|
||||
* P.times, P.todp, P.toExponential, P.toFixed, P.pow, P.toPrecision, P.tosd,
|
||||
* divide, getLn10, exp, ln
|
||||
* subtract P.minus, P.plus
|
||||
* toString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf
|
||||
* truncate P.pow
|
||||
*
|
||||
* Throws: P.log, P.mod, P.sd, P.sqrt, P.pow, checkInt32, divide, round,
|
||||
* getLn10, exp, ln, parseDecimal, Decimal, config
|
||||
*/
|
||||
|
||||
|
||||
function add(x, y) {
|
||||
var carry, d, e, i, k, len, xd, yd,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
// If either is zero...
|
||||
if (!x.s || !y.s) {
|
||||
|
||||
// Return x if y is zero.
|
||||
// Return y if y is non-zero.
|
||||
if (!y.s) y = new Ctor(x);
|
||||
return external ? round(y, pr) : y;
|
||||
}
|
||||
|
||||
xd = x.d;
|
||||
yd = y.d;
|
||||
|
||||
// x and y are finite, non-zero numbers with the same sign.
|
||||
|
||||
k = x.e;
|
||||
e = y.e;
|
||||
xd = xd.slice();
|
||||
i = k - e;
|
||||
|
||||
// If base 1e7 exponents differ...
|
||||
if (i) {
|
||||
if (i < 0) {
|
||||
d = xd;
|
||||
i = -i;
|
||||
len = yd.length;
|
||||
} else {
|
||||
d = yd;
|
||||
e = k;
|
||||
len = xd.length;
|
||||
}
|
||||
|
||||
// Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1.
|
||||
k = Math.ceil(pr / LOG_BASE);
|
||||
len = k > len ? k + 1 : len + 1;
|
||||
|
||||
if (i > len) {
|
||||
i = len;
|
||||
d.length = 1;
|
||||
}
|
||||
|
||||
// Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts.
|
||||
d.reverse();
|
||||
for (; i--;) d.push(0);
|
||||
d.reverse();
|
||||
}
|
||||
|
||||
len = xd.length;
|
||||
i = yd.length;
|
||||
|
||||
// If yd is longer than xd, swap xd and yd so xd points to the longer array.
|
||||
if (len - i < 0) {
|
||||
i = len;
|
||||
d = yd;
|
||||
yd = xd;
|
||||
xd = d;
|
||||
}
|
||||
|
||||
// Only start adding at yd.length - 1 as the further digits of xd can be left as they are.
|
||||
for (carry = 0; i;) {
|
||||
carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0;
|
||||
xd[i] %= BASE;
|
||||
}
|
||||
|
||||
if (carry) {
|
||||
xd.unshift(carry);
|
||||
++e;
|
||||
}
|
||||
|
||||
// Remove trailing zeros.
|
||||
// No need to check for zero, as +x + +y != 0 && -x + -y != 0
|
||||
for (len = xd.length; xd[--len] == 0;) xd.pop();
|
||||
|
||||
y.d = xd;
|
||||
y.e = e;
|
||||
|
||||
return external ? round(y, pr) : y;
|
||||
}
|
||||
|
||||
|
||||
function checkInt32(i, min, max) {
|
||||
if (i !== ~~i || i < min || i > max) {
|
||||
throw Error(invalidArgument + i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function digitsToString(d) {
|
||||
var i, k, ws,
|
||||
indexOfLastWord = d.length - 1,
|
||||
str = '',
|
||||
w = d[0];
|
||||
|
||||
if (indexOfLastWord > 0) {
|
||||
str += w;
|
||||
for (i = 1; i < indexOfLastWord; i++) {
|
||||
ws = d[i] + '';
|
||||
k = LOG_BASE - ws.length;
|
||||
if (k) str += getZeroString(k);
|
||||
str += ws;
|
||||
}
|
||||
|
||||
w = d[i];
|
||||
ws = w + '';
|
||||
k = LOG_BASE - ws.length;
|
||||
if (k) str += getZeroString(k);
|
||||
} else if (w === 0) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// Remove trailing zeros of last w.
|
||||
for (; w % 10 === 0;) w /= 10;
|
||||
|
||||
return str + w;
|
||||
}
|
||||
|
||||
|
||||
var divide = (function () {
|
||||
|
||||
// Assumes non-zero x and k, and hence non-zero result.
|
||||
function multiplyInteger(x, k) {
|
||||
var temp,
|
||||
carry = 0,
|
||||
i = x.length;
|
||||
|
||||
for (x = x.slice(); i--;) {
|
||||
temp = x[i] * k + carry;
|
||||
x[i] = temp % BASE | 0;
|
||||
carry = temp / BASE | 0;
|
||||
}
|
||||
|
||||
if (carry) x.unshift(carry);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
function compare(a, b, aL, bL) {
|
||||
var i, r;
|
||||
|
||||
if (aL != bL) {
|
||||
r = aL > bL ? 1 : -1;
|
||||
} else {
|
||||
for (i = r = 0; i < aL; i++) {
|
||||
if (a[i] != b[i]) {
|
||||
r = a[i] > b[i] ? 1 : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
function subtract(a, b, aL) {
|
||||
var i = 0;
|
||||
|
||||
// Subtract b from a.
|
||||
for (; aL--;) {
|
||||
a[aL] -= i;
|
||||
i = a[aL] < b[aL] ? 1 : 0;
|
||||
a[aL] = i * BASE + a[aL] - b[aL];
|
||||
}
|
||||
|
||||
// Remove leading zeros.
|
||||
for (; !a[0] && a.length > 1;) a.shift();
|
||||
}
|
||||
|
||||
return function (x, y, pr, dp) {
|
||||
var cmp, e, i, k, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, yL, yz,
|
||||
Ctor = x.constructor,
|
||||
sign = x.s == y.s ? 1 : -1,
|
||||
xd = x.d,
|
||||
yd = y.d;
|
||||
|
||||
// Either 0?
|
||||
if (!x.s) return new Ctor(x);
|
||||
if (!y.s) throw Error(decimalError + 'Division by zero');
|
||||
|
||||
e = x.e - y.e;
|
||||
yL = yd.length;
|
||||
xL = xd.length;
|
||||
q = new Ctor(sign);
|
||||
qd = q.d = [];
|
||||
|
||||
// Result exponent may be one less than e.
|
||||
for (i = 0; yd[i] == (xd[i] || 0); ) ++i;
|
||||
if (yd[i] > (xd[i] || 0)) --e;
|
||||
|
||||
if (pr == null) {
|
||||
sd = pr = Ctor.precision;
|
||||
} else if (dp) {
|
||||
sd = pr + (getBase10Exponent(x) - getBase10Exponent(y)) + 1;
|
||||
} else {
|
||||
sd = pr;
|
||||
}
|
||||
|
||||
if (sd < 0) return new Ctor(0);
|
||||
|
||||
// Convert precision in number of base 10 digits to base 1e7 digits.
|
||||
sd = sd / LOG_BASE + 2 | 0;
|
||||
i = 0;
|
||||
|
||||
// divisor < 1e7
|
||||
if (yL == 1) {
|
||||
k = 0;
|
||||
yd = yd[0];
|
||||
sd++;
|
||||
|
||||
// k is the carry.
|
||||
for (; (i < xL || k) && sd--; i++) {
|
||||
t = k * BASE + (xd[i] || 0);
|
||||
qd[i] = t / yd | 0;
|
||||
k = t % yd | 0;
|
||||
}
|
||||
|
||||
// divisor >= 1e7
|
||||
} else {
|
||||
|
||||
// Normalise xd and yd so highest order digit of yd is >= BASE/2
|
||||
k = BASE / (yd[0] + 1) | 0;
|
||||
|
||||
if (k > 1) {
|
||||
yd = multiplyInteger(yd, k);
|
||||
xd = multiplyInteger(xd, k);
|
||||
yL = yd.length;
|
||||
xL = xd.length;
|
||||
}
|
||||
|
||||
xi = yL;
|
||||
rem = xd.slice(0, yL);
|
||||
remL = rem.length;
|
||||
|
||||
// Add zeros to make remainder as long as divisor.
|
||||
for (; remL < yL;) rem[remL++] = 0;
|
||||
|
||||
yz = yd.slice();
|
||||
yz.unshift(0);
|
||||
yd0 = yd[0];
|
||||
|
||||
if (yd[1] >= BASE / 2) ++yd0;
|
||||
|
||||
do {
|
||||
k = 0;
|
||||
|
||||
// Compare divisor and remainder.
|
||||
cmp = compare(yd, rem, yL, remL);
|
||||
|
||||
// If divisor < remainder.
|
||||
if (cmp < 0) {
|
||||
|
||||
// Calculate trial digit, k.
|
||||
rem0 = rem[0];
|
||||
if (yL != remL) rem0 = rem0 * BASE + (rem[1] || 0);
|
||||
|
||||
// k will be how many times the divisor goes into the current remainder.
|
||||
k = rem0 / yd0 | 0;
|
||||
|
||||
// Algorithm:
|
||||
// 1. product = divisor * trial digit (k)
|
||||
// 2. if product > remainder: product -= divisor, k--
|
||||
// 3. remainder -= product
|
||||
// 4. if product was < remainder at 2:
|
||||
// 5. compare new remainder and divisor
|
||||
// 6. If remainder > divisor: remainder -= divisor, k++
|
||||
|
||||
if (k > 1) {
|
||||
if (k >= BASE) k = BASE - 1;
|
||||
|
||||
// product = divisor * trial digit.
|
||||
prod = multiplyInteger(yd, k);
|
||||
prodL = prod.length;
|
||||
remL = rem.length;
|
||||
|
||||
// Compare product and remainder.
|
||||
cmp = compare(prod, rem, prodL, remL);
|
||||
|
||||
// product > remainder.
|
||||
if (cmp == 1) {
|
||||
k--;
|
||||
|
||||
// Subtract divisor from product.
|
||||
subtract(prod, yL < prodL ? yz : yd, prodL);
|
||||
}
|
||||
} else {
|
||||
|
||||
// cmp is -1.
|
||||
// If k is 0, there is no need to compare yd and rem again below, so change cmp to 1
|
||||
// to avoid it. If k is 1 there is a need to compare yd and rem again below.
|
||||
if (k == 0) cmp = k = 1;
|
||||
prod = yd.slice();
|
||||
}
|
||||
|
||||
prodL = prod.length;
|
||||
if (prodL < remL) prod.unshift(0);
|
||||
|
||||
// Subtract product from remainder.
|
||||
subtract(rem, prod, remL);
|
||||
|
||||
// If product was < previous remainder.
|
||||
if (cmp == -1) {
|
||||
remL = rem.length;
|
||||
|
||||
// Compare divisor and new remainder.
|
||||
cmp = compare(yd, rem, yL, remL);
|
||||
|
||||
// If divisor < new remainder, subtract divisor from remainder.
|
||||
if (cmp < 1) {
|
||||
k++;
|
||||
|
||||
// Subtract divisor from remainder.
|
||||
subtract(rem, yL < remL ? yz : yd, remL);
|
||||
}
|
||||
}
|
||||
|
||||
remL = rem.length;
|
||||
} else if (cmp === 0) {
|
||||
k++;
|
||||
rem = [0];
|
||||
} // if cmp === 1, k will be 0
|
||||
|
||||
// Add the next digit, k, to the result array.
|
||||
qd[i++] = k;
|
||||
|
||||
// Update the remainder.
|
||||
if (cmp && rem[0]) {
|
||||
rem[remL++] = xd[xi] || 0;
|
||||
} else {
|
||||
rem = [xd[xi]];
|
||||
remL = 1;
|
||||
}
|
||||
|
||||
} while ((xi++ < xL || rem[0] !== void 0) && sd--);
|
||||
}
|
||||
|
||||
// Leading zero?
|
||||
if (!qd[0]) qd.shift();
|
||||
|
||||
q.e = e;
|
||||
|
||||
return round(q, dp ? pr + getBase10Exponent(q) + 1 : pr);
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the natural exponential of `x` truncated to `sd`
|
||||
* significant digits.
|
||||
*
|
||||
* Taylor/Maclaurin series.
|
||||
*
|
||||
* exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ...
|
||||
*
|
||||
* Argument reduction:
|
||||
* Repeat x = x / 32, k += 5, until |x| < 0.1
|
||||
* exp(x) = exp(x / 2^k)^(2^k)
|
||||
*
|
||||
* Previously, the argument was initially reduced by
|
||||
* exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10)
|
||||
* to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was
|
||||
* found to be slower than just dividing repeatedly by 32 as above.
|
||||
*
|
||||
* (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324)
|
||||
*
|
||||
* exp(x) is non-terminating for any finite, non-zero x.
|
||||
*
|
||||
*/
|
||||
function exp(x, sd) {
|
||||
var denominator, guard, pow, sum, t, wpr,
|
||||
i = 0,
|
||||
k = 0,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
if (getBase10Exponent(x) > 16) throw Error(exponentOutOfRange + getBase10Exponent(x));
|
||||
|
||||
// exp(0) = 1
|
||||
if (!x.s) return new Ctor(ONE);
|
||||
|
||||
if (sd == null) {
|
||||
external = false;
|
||||
wpr = pr;
|
||||
} else {
|
||||
wpr = sd;
|
||||
}
|
||||
|
||||
t = new Ctor(0.03125);
|
||||
|
||||
while (x.abs().gte(0.1)) {
|
||||
x = x.times(t); // x = x / 2^5
|
||||
k += 5;
|
||||
}
|
||||
|
||||
// Estimate the precision increase necessary to ensure the first 4 rounding digits are correct.
|
||||
guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0;
|
||||
wpr += guard;
|
||||
denominator = pow = sum = new Ctor(ONE);
|
||||
Ctor.precision = wpr;
|
||||
|
||||
for (;;) {
|
||||
pow = round(pow.times(x), wpr);
|
||||
denominator = denominator.times(++i);
|
||||
t = sum.plus(divide(pow, denominator, wpr));
|
||||
|
||||
if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {
|
||||
while (k--) sum = round(sum.times(sum), wpr);
|
||||
Ctor.precision = pr;
|
||||
return sd == null ? (external = true, round(sum, pr)) : sum;
|
||||
}
|
||||
|
||||
sum = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate the base 10 exponent from the base 1e7 exponent.
|
||||
function getBase10Exponent(x) {
|
||||
var e = x.e * LOG_BASE,
|
||||
w = x.d[0];
|
||||
|
||||
// Add the number of digits of the first word of the digits array.
|
||||
for (; w >= 10; w /= 10) e++;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
function getLn10(Ctor, sd, pr) {
|
||||
|
||||
if (sd > Ctor.LN10.sd()) {
|
||||
|
||||
|
||||
// Reset global state in case the exception is caught.
|
||||
external = true;
|
||||
if (pr) Ctor.precision = pr;
|
||||
throw Error(decimalError + 'LN10 precision limit exceeded');
|
||||
}
|
||||
|
||||
return round(new Ctor(Ctor.LN10), sd);
|
||||
}
|
||||
|
||||
|
||||
function getZeroString(k) {
|
||||
var zs = '';
|
||||
for (; k--;) zs += '0';
|
||||
return zs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the natural logarithm of `x` truncated to `sd` significant
|
||||
* digits.
|
||||
*
|
||||
* ln(n) is non-terminating (n != 1)
|
||||
*
|
||||
*/
|
||||
function ln(y, sd) {
|
||||
var c, c0, denominator, e, numerator, sum, t, wpr, x2,
|
||||
n = 1,
|
||||
guard = 10,
|
||||
x = y,
|
||||
xd = x.d,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
// ln(-x) = NaN
|
||||
// ln(0) = -Infinity
|
||||
if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity'));
|
||||
|
||||
// ln(1) = 0
|
||||
if (x.eq(ONE)) return new Ctor(0);
|
||||
|
||||
if (sd == null) {
|
||||
external = false;
|
||||
wpr = pr;
|
||||
} else {
|
||||
wpr = sd;
|
||||
}
|
||||
|
||||
if (x.eq(10)) {
|
||||
if (sd == null) external = true;
|
||||
return getLn10(Ctor, wpr);
|
||||
}
|
||||
|
||||
wpr += guard;
|
||||
Ctor.precision = wpr;
|
||||
c = digitsToString(xd);
|
||||
c0 = c.charAt(0);
|
||||
e = getBase10Exponent(x);
|
||||
|
||||
if (Math.abs(e) < 1.5e15) {
|
||||
|
||||
// Argument reduction.
|
||||
// The series converges faster the closer the argument is to 1, so using
|
||||
// ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b
|
||||
// multiply the argument by itself until the leading digits of the significand are 7, 8, 9,
|
||||
// 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can
|
||||
// later be divided by this number, then separate out the power of 10 using
|
||||
// ln(a*10^b) = ln(a) + b*ln(10).
|
||||
|
||||
// max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14).
|
||||
//while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) {
|
||||
// max n is 6 (gives 0.7 - 1.3)
|
||||
while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) {
|
||||
x = x.times(y);
|
||||
c = digitsToString(x.d);
|
||||
c0 = c.charAt(0);
|
||||
n++;
|
||||
}
|
||||
|
||||
e = getBase10Exponent(x);
|
||||
|
||||
if (c0 > 1) {
|
||||
x = new Ctor('0.' + c);
|
||||
e++;
|
||||
} else {
|
||||
x = new Ctor(c0 + '.' + c.slice(1));
|
||||
}
|
||||
} else {
|
||||
|
||||
// The argument reduction method above may result in overflow if the argument y is a massive
|
||||
// number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this
|
||||
// function using ln(x*10^e) = ln(x) + e*ln(10).
|
||||
t = getLn10(Ctor, wpr + 2, pr).times(e + '');
|
||||
x = ln(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t);
|
||||
|
||||
Ctor.precision = pr;
|
||||
return sd == null ? (external = true, round(x, pr)) : x;
|
||||
}
|
||||
|
||||
// x is reduced to a value near 1.
|
||||
|
||||
// Taylor series.
|
||||
// ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...)
|
||||
// where x = (y - 1)/(y + 1) (|x| < 1)
|
||||
sum = numerator = x = divide(x.minus(ONE), x.plus(ONE), wpr);
|
||||
x2 = round(x.times(x), wpr);
|
||||
denominator = 3;
|
||||
|
||||
for (;;) {
|
||||
numerator = round(numerator.times(x2), wpr);
|
||||
t = sum.plus(divide(numerator, new Ctor(denominator), wpr));
|
||||
|
||||
if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {
|
||||
sum = sum.times(2);
|
||||
|
||||
// Reverse the argument reduction.
|
||||
if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + ''));
|
||||
sum = divide(sum, new Ctor(n), wpr);
|
||||
|
||||
Ctor.precision = pr;
|
||||
return sd == null ? (external = true, round(sum, pr)) : sum;
|
||||
}
|
||||
|
||||
sum = t;
|
||||
denominator += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse the value of a new Decimal `x` from string `str`.
|
||||
*/
|
||||
function parseDecimal(x, str) {
|
||||
var e, i, len;
|
||||
|
||||
// Decimal point?
|
||||
if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
|
||||
|
||||
// Exponential form?
|
||||
if ((i = str.search(/e/i)) > 0) {
|
||||
|
||||
// Determine exponent.
|
||||
if (e < 0) e = i;
|
||||
e += +str.slice(i + 1);
|
||||
str = str.substring(0, i);
|
||||
} else if (e < 0) {
|
||||
|
||||
// Integer.
|
||||
e = str.length;
|
||||
}
|
||||
|
||||
// Determine leading zeros.
|
||||
for (i = 0; str.charCodeAt(i) === 48;) ++i;
|
||||
|
||||
// Determine trailing zeros.
|
||||
for (len = str.length; str.charCodeAt(len - 1) === 48;) --len;
|
||||
str = str.slice(i, len);
|
||||
|
||||
if (str) {
|
||||
len -= i;
|
||||
e = e - i - 1;
|
||||
x.e = mathfloor(e / LOG_BASE);
|
||||
x.d = [];
|
||||
|
||||
// Transform base
|
||||
|
||||
// e is the base 10 exponent.
|
||||
// i is where to slice str to get the first word of the digits array.
|
||||
i = (e + 1) % LOG_BASE;
|
||||
if (e < 0) i += LOG_BASE;
|
||||
|
||||
if (i < len) {
|
||||
if (i) x.d.push(+str.slice(0, i));
|
||||
for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE));
|
||||
str = str.slice(i);
|
||||
i = LOG_BASE - str.length;
|
||||
} else {
|
||||
i -= len;
|
||||
}
|
||||
|
||||
for (; i--;) str += '0';
|
||||
x.d.push(+str);
|
||||
|
||||
if (external && (x.e > MAX_E || x.e < -MAX_E)) throw Error(exponentOutOfRange + e);
|
||||
} else {
|
||||
|
||||
// Zero.
|
||||
x.s = 0;
|
||||
x.e = 0;
|
||||
x.d = [0];
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Round `x` to `sd` significant digits, using rounding mode `rm` if present (truncate otherwise).
|
||||
*/
|
||||
function round(x, sd, rm) {
|
||||
var i, j, k, n, rd, doRound, w, xdi,
|
||||
xd = x.d;
|
||||
|
||||
// rd: the rounding digit, i.e. the digit after the digit that may be rounded up.
|
||||
// w: the word of xd which contains the rounding digit, a base 1e7 number.
|
||||
// xdi: the index of w within xd.
|
||||
// n: the number of digits of w.
|
||||
// i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if
|
||||
// they had leading zeros)
|
||||
// j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero).
|
||||
|
||||
// Get the length of the first word of the digits array xd.
|
||||
for (n = 1, k = xd[0]; k >= 10; k /= 10) n++;
|
||||
i = sd - n;
|
||||
|
||||
// Is the rounding digit in the first word of xd?
|
||||
if (i < 0) {
|
||||
i += LOG_BASE;
|
||||
j = sd;
|
||||
w = xd[xdi = 0];
|
||||
} else {
|
||||
xdi = Math.ceil((i + 1) / LOG_BASE);
|
||||
k = xd.length;
|
||||
if (xdi >= k) return x;
|
||||
w = k = xd[xdi];
|
||||
|
||||
// Get the number of digits of w.
|
||||
for (n = 1; k >= 10; k /= 10) n++;
|
||||
|
||||
// Get the index of rd within w.
|
||||
i %= LOG_BASE;
|
||||
|
||||
// Get the index of rd within w, adjusted for leading zeros.
|
||||
// The number of leading zeros of w is given by LOG_BASE - n.
|
||||
j = i - LOG_BASE + n;
|
||||
}
|
||||
|
||||
if (rm !== void 0) {
|
||||
k = mathpow(10, n - j - 1);
|
||||
|
||||
// Get the rounding digit at index j of w.
|
||||
rd = w / k % 10 | 0;
|
||||
|
||||
// Are there any non-zero digits after the rounding digit?
|
||||
doRound = sd < 0 || xd[xdi + 1] !== void 0 || w % k;
|
||||
|
||||
// The expression `w % mathpow(10, n - j - 1)` returns all the digits of w to the right of the
|
||||
// digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression will give
|
||||
// 714.
|
||||
|
||||
doRound = rm < 4
|
||||
? (rd || doRound) && (rm == 0 || rm == (x.s < 0 ? 3 : 2))
|
||||
: rd > 5 || rd == 5 && (rm == 4 || doRound || rm == 6 &&
|
||||
|
||||
// Check whether the digit to the left of the rounding digit is odd.
|
||||
((i > 0 ? j > 0 ? w / mathpow(10, n - j) : 0 : xd[xdi - 1]) % 10) & 1 ||
|
||||
rm == (x.s < 0 ? 8 : 7));
|
||||
}
|
||||
|
||||
if (sd < 1 || !xd[0]) {
|
||||
if (doRound) {
|
||||
k = getBase10Exponent(x);
|
||||
xd.length = 1;
|
||||
|
||||
// Convert sd to decimal places.
|
||||
sd = sd - k - 1;
|
||||
|
||||
// 1, 0.1, 0.01, 0.001, 0.0001 etc.
|
||||
xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE);
|
||||
x.e = mathfloor(-sd / LOG_BASE) || 0;
|
||||
} else {
|
||||
xd.length = 1;
|
||||
|
||||
// Zero.
|
||||
xd[0] = x.e = x.s = 0;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// Remove excess digits.
|
||||
if (i == 0) {
|
||||
xd.length = xdi;
|
||||
k = 1;
|
||||
xdi--;
|
||||
} else {
|
||||
xd.length = xdi + 1;
|
||||
k = mathpow(10, LOG_BASE - i);
|
||||
|
||||
// E.g. 56700 becomes 56000 if 7 is the rounding digit.
|
||||
// j > 0 means i > number of leading zeros of w.
|
||||
xd[xdi] = j > 0 ? (w / mathpow(10, n - j) % mathpow(10, j) | 0) * k : 0;
|
||||
}
|
||||
|
||||
if (doRound) {
|
||||
for (;;) {
|
||||
|
||||
// Is the digit to be rounded up in the first word of xd?
|
||||
if (xdi == 0) {
|
||||
if ((xd[0] += k) == BASE) {
|
||||
xd[0] = 1;
|
||||
++x.e;
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
xd[xdi] += k;
|
||||
if (xd[xdi] != BASE) break;
|
||||
xd[xdi--] = 0;
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove trailing zeros.
|
||||
for (i = xd.length; xd[--i] === 0;) xd.pop();
|
||||
|
||||
if (external && (x.e > MAX_E || x.e < -MAX_E)) {
|
||||
throw Error(exponentOutOfRange + getBase10Exponent(x));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
function subtract(x, y) {
|
||||
var d, e, i, j, k, len, xd, xe, xLTy, yd,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
// Return y negated if x is zero.
|
||||
// Return x if y is zero and x is non-zero.
|
||||
if (!x.s || !y.s) {
|
||||
if (y.s) y.s = -y.s;
|
||||
else y = new Ctor(x);
|
||||
return external ? round(y, pr) : y;
|
||||
}
|
||||
|
||||
xd = x.d;
|
||||
yd = y.d;
|
||||
|
||||
// x and y are non-zero numbers with the same sign.
|
||||
|
||||
e = y.e;
|
||||
xe = x.e;
|
||||
xd = xd.slice();
|
||||
k = xe - e;
|
||||
|
||||
// If exponents differ...
|
||||
if (k) {
|
||||
xLTy = k < 0;
|
||||
|
||||
if (xLTy) {
|
||||
d = xd;
|
||||
k = -k;
|
||||
len = yd.length;
|
||||
} else {
|
||||
d = yd;
|
||||
e = xe;
|
||||
len = xd.length;
|
||||
}
|
||||
|
||||
// Numbers with massively different exponents would result in a very high number of zeros
|
||||
// needing to be prepended, but this can be avoided while still ensuring correct rounding by
|
||||
// limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`.
|
||||
i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2;
|
||||
|
||||
if (k > i) {
|
||||
k = i;
|
||||
d.length = 1;
|
||||
}
|
||||
|
||||
// Prepend zeros to equalise exponents.
|
||||
d.reverse();
|
||||
for (i = k; i--;) d.push(0);
|
||||
d.reverse();
|
||||
|
||||
// Base 1e7 exponents equal.
|
||||
} else {
|
||||
|
||||
// Check digits to determine which is the bigger number.
|
||||
|
||||
i = xd.length;
|
||||
len = yd.length;
|
||||
xLTy = i < len;
|
||||
if (xLTy) len = i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (xd[i] != yd[i]) {
|
||||
xLTy = xd[i] < yd[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
}
|
||||
|
||||
if (xLTy) {
|
||||
d = xd;
|
||||
xd = yd;
|
||||
yd = d;
|
||||
y.s = -y.s;
|
||||
}
|
||||
|
||||
len = xd.length;
|
||||
|
||||
// Append zeros to xd if shorter.
|
||||
// Don't add zeros to yd if shorter as subtraction only needs to start at yd length.
|
||||
for (i = yd.length - len; i > 0; --i) xd[len++] = 0;
|
||||
|
||||
// Subtract yd from xd.
|
||||
for (i = yd.length; i > k;) {
|
||||
if (xd[--i] < yd[i]) {
|
||||
for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1;
|
||||
--xd[j];
|
||||
xd[i] += BASE;
|
||||
}
|
||||
|
||||
xd[i] -= yd[i];
|
||||
}
|
||||
|
||||
// Remove trailing zeros.
|
||||
for (; xd[--len] === 0;) xd.pop();
|
||||
|
||||
// Remove leading zeros and adjust exponent accordingly.
|
||||
for (; xd[0] === 0; xd.shift()) --e;
|
||||
|
||||
// Zero?
|
||||
if (!xd[0]) return new Ctor(0);
|
||||
|
||||
y.d = xd;
|
||||
y.e = e;
|
||||
|
||||
//return external && xd.length >= pr / LOG_BASE ? round(y, pr) : y;
|
||||
return external ? round(y, pr) : y;
|
||||
}
|
||||
|
||||
|
||||
function toString(x, isExp, sd) {
|
||||
var k,
|
||||
e = getBase10Exponent(x),
|
||||
str = digitsToString(x.d),
|
||||
len = str.length;
|
||||
|
||||
if (isExp) {
|
||||
if (sd && (k = sd - len) > 0) {
|
||||
str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k);
|
||||
} else if (len > 1) {
|
||||
str = str.charAt(0) + '.' + str.slice(1);
|
||||
}
|
||||
|
||||
str = str + (e < 0 ? 'e' : 'e+') + e;
|
||||
} else if (e < 0) {
|
||||
str = '0.' + getZeroString(-e - 1) + str;
|
||||
if (sd && (k = sd - len) > 0) str += getZeroString(k);
|
||||
} else if (e >= len) {
|
||||
str += getZeroString(e + 1 - len);
|
||||
if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k);
|
||||
} else {
|
||||
if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k);
|
||||
if (sd && (k = sd - len) > 0) {
|
||||
if (e + 1 === len) str += '.';
|
||||
str += getZeroString(k);
|
||||
}
|
||||
}
|
||||
|
||||
return x.s < 0 ? '-' + str : str;
|
||||
}
|
||||
|
||||
|
||||
// Does not strip trailing zeros.
|
||||
function truncate(arr, len) {
|
||||
if (arr.length > len) {
|
||||
arr.length = len;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Decimal methods
|
||||
|
||||
|
||||
/*
|
||||
* clone
|
||||
* config/set
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Create and return a Decimal constructor with the same configuration properties as this Decimal
|
||||
* constructor.
|
||||
*
|
||||
*/
|
||||
function clone(obj) {
|
||||
var i, p, ps;
|
||||
|
||||
/*
|
||||
* The Decimal constructor and exported function.
|
||||
* Return a new Decimal instance.
|
||||
*
|
||||
* value {number|string|Decimal} A numeric value.
|
||||
*
|
||||
*/
|
||||
function Decimal(value) {
|
||||
var x = this;
|
||||
|
||||
// Decimal called without new.
|
||||
if (!(x instanceof Decimal)) return new Decimal(value);
|
||||
|
||||
// Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor
|
||||
// which points to Object.
|
||||
x.constructor = Decimal;
|
||||
|
||||
// Duplicate.
|
||||
if (value instanceof Decimal) {
|
||||
x.s = value.s;
|
||||
x.e = value.e;
|
||||
x.d = (value = value.d) ? value.slice() : value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof value === 'number') {
|
||||
|
||||
// Reject Infinity/NaN.
|
||||
if (value * 0 !== 0) {
|
||||
throw Error(invalidArgument + value);
|
||||
}
|
||||
|
||||
if (value > 0) {
|
||||
x.s = 1;
|
||||
} else if (value < 0) {
|
||||
value = -value;
|
||||
x.s = -1;
|
||||
} else {
|
||||
x.s = 0;
|
||||
x.e = 0;
|
||||
x.d = [0];
|
||||
return;
|
||||
}
|
||||
|
||||
// Fast path for small integers.
|
||||
if (value === ~~value && value < 1e7) {
|
||||
x.e = 0;
|
||||
x.d = [value];
|
||||
return;
|
||||
}
|
||||
|
||||
return parseDecimal(x, value.toString());
|
||||
} else if (typeof value !== 'string') {
|
||||
throw Error(invalidArgument + value);
|
||||
}
|
||||
|
||||
// Minus sign?
|
||||
if (value.charCodeAt(0) === 45) {
|
||||
value = value.slice(1);
|
||||
x.s = -1;
|
||||
} else {
|
||||
x.s = 1;
|
||||
}
|
||||
|
||||
if (isDecimal.test(value)) parseDecimal(x, value);
|
||||
else throw Error(invalidArgument + value);
|
||||
}
|
||||
|
||||
Decimal.prototype = P;
|
||||
|
||||
Decimal.ROUND_UP = 0;
|
||||
Decimal.ROUND_DOWN = 1;
|
||||
Decimal.ROUND_CEIL = 2;
|
||||
Decimal.ROUND_FLOOR = 3;
|
||||
Decimal.ROUND_HALF_UP = 4;
|
||||
Decimal.ROUND_HALF_DOWN = 5;
|
||||
Decimal.ROUND_HALF_EVEN = 6;
|
||||
Decimal.ROUND_HALF_CEIL = 7;
|
||||
Decimal.ROUND_HALF_FLOOR = 8;
|
||||
|
||||
Decimal.clone = clone;
|
||||
Decimal.config = Decimal.set = config;
|
||||
|
||||
if (obj === void 0) obj = {};
|
||||
if (obj) {
|
||||
ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'LN10'];
|
||||
for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p];
|
||||
}
|
||||
|
||||
Decimal.config(obj);
|
||||
|
||||
return Decimal;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Configure global settings for a Decimal constructor.
|
||||
*
|
||||
* `obj` is an object with one or more of the following properties,
|
||||
*
|
||||
* precision {number}
|
||||
* rounding {number}
|
||||
* toExpNeg {number}
|
||||
* toExpPos {number}
|
||||
*
|
||||
* E.g. Decimal.config({ precision: 20, rounding: 4 })
|
||||
*
|
||||
*/
|
||||
function config(obj) {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
throw Error(decimalError + 'Object expected');
|
||||
}
|
||||
var i, p, v,
|
||||
ps = [
|
||||
'precision', 1, MAX_DIGITS,
|
||||
'rounding', 0, 8,
|
||||
'toExpNeg', -1 / 0, 0,
|
||||
'toExpPos', 0, 1 / 0
|
||||
];
|
||||
|
||||
for (i = 0; i < ps.length; i += 3) {
|
||||
if ((v = obj[p = ps[i]]) !== void 0) {
|
||||
if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v;
|
||||
else throw Error(invalidArgument + p + ': ' + v);
|
||||
}
|
||||
}
|
||||
|
||||
if ((v = obj[p = 'LN10']) !== void 0) {
|
||||
if (v == Math.LN10) this[p] = new this(v);
|
||||
else throw Error(invalidArgument + p + ': ' + v);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Create and configure initial Decimal constructor.
|
||||
Decimal = clone(Decimal);
|
||||
|
||||
Decimal['default'] = Decimal.Decimal = Decimal;
|
||||
|
||||
// Internal constant.
|
||||
ONE = new Decimal(1);
|
||||
|
||||
|
||||
// Export.
|
||||
|
||||
|
||||
// AMD.
|
||||
if (typeof define == 'function' && define.amd) {
|
||||
define(function () {
|
||||
return Decimal;
|
||||
});
|
||||
|
||||
// Node and other environments that support module.exports.
|
||||
} else if (typeof module != 'undefined' && module.exports) {
|
||||
module.exports = Decimal;
|
||||
|
||||
// Browser.
|
||||
} else {
|
||||
if (!globalScope) {
|
||||
globalScope = typeof self != 'undefined' && self && self.self == self
|
||||
? self : Function('return this')();
|
||||
}
|
||||
|
||||
globalScope.Decimal = Decimal;
|
||||
}
|
||||
})(this);
|
||||
+3
File diff suppressed because one or more lines are too long
+1985
@@ -0,0 +1,1985 @@
|
||||
/*
|
||||
* decimal.js-light v2.5.1
|
||||
* An arbitrary-precision Decimal type for JavaScript.
|
||||
* https://github.com/MikeMcl/decimal.js-light
|
||||
* Copyright (c) 2020 Michael Mclaughlin <M8ch88l@gmail.com>
|
||||
* MIT Expat Licence
|
||||
*/
|
||||
|
||||
|
||||
// ------------------------------------ EDITABLE DEFAULTS ------------------------------------- //
|
||||
|
||||
|
||||
// The limit on the value of `precision`, and on the value of the first argument to
|
||||
// `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`.
|
||||
var MAX_DIGITS = 1e9, // 0 to 1e9
|
||||
|
||||
|
||||
// The initial configuration properties of the Decimal constructor.
|
||||
defaults = {
|
||||
|
||||
// These values must be integers within the stated ranges (inclusive).
|
||||
// Most of these values can be changed during run-time using `Decimal.config`.
|
||||
|
||||
// The maximum number of significant digits of the result of a calculation or base conversion.
|
||||
// E.g. `Decimal.config({ precision: 20 });`
|
||||
precision: 20, // 1 to MAX_DIGITS
|
||||
|
||||
// The rounding mode used by default by `toInteger`, `toDecimalPlaces`, `toExponential`,
|
||||
// `toFixed`, `toPrecision` and `toSignificantDigits`.
|
||||
//
|
||||
// ROUND_UP 0 Away from zero.
|
||||
// ROUND_DOWN 1 Towards zero.
|
||||
// ROUND_CEIL 2 Towards +Infinity.
|
||||
// ROUND_FLOOR 3 Towards -Infinity.
|
||||
// ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up.
|
||||
// ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down.
|
||||
// ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour.
|
||||
// ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity.
|
||||
// ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
|
||||
//
|
||||
// E.g.
|
||||
// `Decimal.rounding = 4;`
|
||||
// `Decimal.rounding = Decimal.ROUND_HALF_UP;`
|
||||
rounding: 4, // 0 to 8
|
||||
|
||||
// The exponent value at and beneath which `toString` returns exponential notation.
|
||||
// JavaScript numbers: -7
|
||||
toExpNeg: -7, // 0 to -MAX_E
|
||||
|
||||
// The exponent value at and above which `toString` returns exponential notation.
|
||||
// JavaScript numbers: 21
|
||||
toExpPos: 21, // 0 to MAX_E
|
||||
|
||||
// The natural logarithm of 10.
|
||||
// 115 digits
|
||||
LN10: '2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286'
|
||||
},
|
||||
|
||||
|
||||
// ------------------------------------ END OF EDITABLE DEFAULTS -------------------------------- //
|
||||
|
||||
|
||||
Decimal,
|
||||
external = true,
|
||||
|
||||
decimalError = '[DecimalError] ',
|
||||
invalidArgument = decimalError + 'Invalid argument: ',
|
||||
exponentOutOfRange = decimalError + 'Exponent out of range: ',
|
||||
|
||||
mathfloor = Math.floor,
|
||||
mathpow = Math.pow,
|
||||
|
||||
isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
|
||||
|
||||
ONE,
|
||||
BASE = 1e7,
|
||||
LOG_BASE = 7,
|
||||
MAX_SAFE_INTEGER = 9007199254740991,
|
||||
MAX_E = mathfloor(MAX_SAFE_INTEGER / LOG_BASE), // 1286742750677284
|
||||
|
||||
// Decimal.prototype object
|
||||
P = {};
|
||||
|
||||
|
||||
// Decimal prototype methods
|
||||
|
||||
|
||||
/*
|
||||
* absoluteValue abs
|
||||
* comparedTo cmp
|
||||
* decimalPlaces dp
|
||||
* dividedBy div
|
||||
* dividedToIntegerBy idiv
|
||||
* equals eq
|
||||
* exponent
|
||||
* greaterThan gt
|
||||
* greaterThanOrEqualTo gte
|
||||
* isInteger isint
|
||||
* isNegative isneg
|
||||
* isPositive ispos
|
||||
* isZero
|
||||
* lessThan lt
|
||||
* lessThanOrEqualTo lte
|
||||
* logarithm log
|
||||
* minus sub
|
||||
* modulo mod
|
||||
* naturalExponential exp
|
||||
* naturalLogarithm ln
|
||||
* negated neg
|
||||
* plus add
|
||||
* precision sd
|
||||
* squareRoot sqrt
|
||||
* times mul
|
||||
* toDecimalPlaces todp
|
||||
* toExponential
|
||||
* toFixed
|
||||
* toInteger toint
|
||||
* toNumber
|
||||
* toPower pow
|
||||
* toPrecision
|
||||
* toSignificantDigits tosd
|
||||
* toString
|
||||
* valueOf val
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the absolute value of this Decimal.
|
||||
*
|
||||
*/
|
||||
P.absoluteValue = P.abs = function () {
|
||||
var x = new this.constructor(this);
|
||||
if (x.s) x.s = 1;
|
||||
return x;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return
|
||||
* 1 if the value of this Decimal is greater than the value of `y`,
|
||||
* -1 if the value of this Decimal is less than the value of `y`,
|
||||
* 0 if they have the same value
|
||||
*
|
||||
*/
|
||||
P.comparedTo = P.cmp = function (y) {
|
||||
var i, j, xdL, ydL,
|
||||
x = this;
|
||||
|
||||
y = new x.constructor(y);
|
||||
|
||||
// Signs differ?
|
||||
if (x.s !== y.s) return x.s || -y.s;
|
||||
|
||||
// Compare exponents.
|
||||
if (x.e !== y.e) return x.e > y.e ^ x.s < 0 ? 1 : -1;
|
||||
|
||||
xdL = x.d.length;
|
||||
ydL = y.d.length;
|
||||
|
||||
// Compare digit by digit.
|
||||
for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) {
|
||||
if (x.d[i] !== y.d[i]) return x.d[i] > y.d[i] ^ x.s < 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
// Compare lengths.
|
||||
return xdL === ydL ? 0 : xdL > ydL ^ x.s < 0 ? 1 : -1;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of decimal places of the value of this Decimal.
|
||||
*
|
||||
*/
|
||||
P.decimalPlaces = P.dp = function () {
|
||||
var x = this,
|
||||
w = x.d.length - 1,
|
||||
dp = (w - x.e) * LOG_BASE;
|
||||
|
||||
// Subtract the number of trailing zeros of the last word.
|
||||
w = x.d[w];
|
||||
if (w) for (; w % 10 == 0; w /= 10) dp--;
|
||||
|
||||
return dp < 0 ? 0 : dp;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal divided by `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.dividedBy = P.div = function (y) {
|
||||
return divide(this, new this.constructor(y));
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the integer part of dividing the value of this Decimal
|
||||
* by the value of `y`, truncated to `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.dividedToIntegerBy = P.idiv = function (y) {
|
||||
var x = this,
|
||||
Ctor = x.constructor;
|
||||
return round(divide(x, new Ctor(y), 0, 1), Ctor.precision);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is equal to the value of `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.equals = P.eq = function (y) {
|
||||
return !this.cmp(y);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the (base 10) exponent value of this Decimal (this.e is the base 10000000 exponent).
|
||||
*
|
||||
*/
|
||||
P.exponent = function () {
|
||||
return getBase10Exponent(this);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is greater than the value of `y`, otherwise return
|
||||
* false.
|
||||
*
|
||||
*/
|
||||
P.greaterThan = P.gt = function (y) {
|
||||
return this.cmp(y) > 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is greater than or equal to the value of `y`,
|
||||
* otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.greaterThanOrEqualTo = P.gte = function (y) {
|
||||
return this.cmp(y) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is an integer, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.isInteger = P.isint = function () {
|
||||
return this.e > this.d.length - 2;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is negative, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.isNegative = P.isneg = function () {
|
||||
return this.s < 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is positive, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.isPositive = P.ispos = function () {
|
||||
return this.s > 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is 0, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.isZero = function () {
|
||||
return this.s === 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is less than `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.lessThan = P.lt = function (y) {
|
||||
return this.cmp(y) < 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the value of this Decimal is less than or equal to `y`, otherwise return false.
|
||||
*
|
||||
*/
|
||||
P.lessThanOrEqualTo = P.lte = function (y) {
|
||||
return this.cmp(y) < 1;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the logarithm of the value of this Decimal to the specified base, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
* If no base is specified, return log[10](x).
|
||||
*
|
||||
* log[base](x) = ln(x) / ln(base)
|
||||
*
|
||||
* The maximum error of the result is 1 ulp (unit in the last place).
|
||||
*
|
||||
* [base] {number|string|Decimal} The base of the logarithm.
|
||||
*
|
||||
*/
|
||||
P.logarithm = P.log = function (base) {
|
||||
var r,
|
||||
x = this,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision,
|
||||
wpr = pr + 5;
|
||||
|
||||
// Default base is 10.
|
||||
if (base === void 0) {
|
||||
base = new Ctor(10);
|
||||
} else {
|
||||
base = new Ctor(base);
|
||||
|
||||
// log[-b](x) = NaN
|
||||
// log[0](x) = NaN
|
||||
// log[1](x) = NaN
|
||||
if (base.s < 1 || base.eq(ONE)) throw Error(decimalError + 'NaN');
|
||||
}
|
||||
|
||||
// log[b](-x) = NaN
|
||||
// log[b](0) = -Infinity
|
||||
if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity'));
|
||||
|
||||
// log[b](1) = 0
|
||||
if (x.eq(ONE)) return new Ctor(0);
|
||||
|
||||
external = false;
|
||||
r = divide(ln(x, wpr), ln(base, wpr), wpr);
|
||||
external = true;
|
||||
|
||||
return round(r, pr);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal minus `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.minus = P.sub = function (y) {
|
||||
var x = this;
|
||||
y = new x.constructor(y);
|
||||
return x.s == y.s ? subtract(x, y) : add(x, (y.s = -y.s, y));
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal modulo `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.modulo = P.mod = function (y) {
|
||||
var q,
|
||||
x = this,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
y = new Ctor(y);
|
||||
|
||||
// x % 0 = NaN
|
||||
if (!y.s) throw Error(decimalError + 'NaN');
|
||||
|
||||
// Return x if x is 0.
|
||||
if (!x.s) return round(new Ctor(x), pr);
|
||||
|
||||
// Prevent rounding of intermediate calculations.
|
||||
external = false;
|
||||
q = divide(x, y, 0, 1).times(y);
|
||||
external = true;
|
||||
|
||||
return x.minus(q);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the natural exponential of the value of this Decimal,
|
||||
* i.e. the base e raised to the power the value of this Decimal, truncated to `precision`
|
||||
* significant digits.
|
||||
*
|
||||
*/
|
||||
P.naturalExponential = P.exp = function () {
|
||||
return exp(this);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the natural logarithm of the value of this Decimal,
|
||||
* truncated to `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.naturalLogarithm = P.ln = function () {
|
||||
return ln(this);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by
|
||||
* -1.
|
||||
*
|
||||
*/
|
||||
P.negated = P.neg = function () {
|
||||
var x = new this.constructor(this);
|
||||
x.s = -x.s || 0;
|
||||
return x;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal plus `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.plus = P.add = function (y) {
|
||||
var x = this;
|
||||
y = new x.constructor(y);
|
||||
return x.s == y.s ? add(x, y) : subtract(x, (y.s = -y.s, y));
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of significant digits of the value of this Decimal.
|
||||
*
|
||||
* [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0.
|
||||
*
|
||||
*/
|
||||
P.precision = P.sd = function (z) {
|
||||
var e, sd, w,
|
||||
x = this;
|
||||
|
||||
if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z);
|
||||
|
||||
e = getBase10Exponent(x) + 1;
|
||||
w = x.d.length - 1;
|
||||
sd = w * LOG_BASE + 1;
|
||||
w = x.d[w];
|
||||
|
||||
// If non-zero...
|
||||
if (w) {
|
||||
|
||||
// Subtract the number of trailing zeros of the last word.
|
||||
for (; w % 10 == 0; w /= 10) sd--;
|
||||
|
||||
// Add the number of digits of the first word.
|
||||
for (w = x.d[0]; w >= 10; w /= 10) sd++;
|
||||
}
|
||||
|
||||
return z && e > sd ? e : sd;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the square root of this Decimal, truncated to `precision`
|
||||
* significant digits.
|
||||
*
|
||||
*/
|
||||
P.squareRoot = P.sqrt = function () {
|
||||
var e, n, pr, r, s, t, wpr,
|
||||
x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
// Negative or zero?
|
||||
if (x.s < 1) {
|
||||
if (!x.s) return new Ctor(0);
|
||||
|
||||
// sqrt(-x) = NaN
|
||||
throw Error(decimalError + 'NaN');
|
||||
}
|
||||
|
||||
e = getBase10Exponent(x);
|
||||
external = false;
|
||||
|
||||
// Initial estimate.
|
||||
s = Math.sqrt(+x);
|
||||
|
||||
// Math.sqrt underflow/overflow?
|
||||
// Pass x to Math.sqrt as integer, then adjust the exponent of the result.
|
||||
if (s == 0 || s == 1 / 0) {
|
||||
n = digitsToString(x.d);
|
||||
if ((n.length + e) % 2 == 0) n += '0';
|
||||
s = Math.sqrt(n);
|
||||
e = mathfloor((e + 1) / 2) - (e < 0 || e % 2);
|
||||
|
||||
if (s == 1 / 0) {
|
||||
n = '5e' + e;
|
||||
} else {
|
||||
n = s.toExponential();
|
||||
n = n.slice(0, n.indexOf('e') + 1) + e;
|
||||
}
|
||||
|
||||
r = new Ctor(n);
|
||||
} else {
|
||||
r = new Ctor(s.toString());
|
||||
}
|
||||
|
||||
pr = Ctor.precision;
|
||||
s = wpr = pr + 3;
|
||||
|
||||
// Newton-Raphson iteration.
|
||||
for (;;) {
|
||||
t = r;
|
||||
r = t.plus(divide(x, t, wpr + 2)).times(0.5);
|
||||
|
||||
if (digitsToString(t.d).slice(0, wpr) === (n = digitsToString(r.d)).slice(0, wpr)) {
|
||||
n = n.slice(wpr - 3, wpr + 1);
|
||||
|
||||
// The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or
|
||||
// 4999, i.e. approaching a rounding boundary, continue the iteration.
|
||||
if (s == wpr && n == '4999') {
|
||||
|
||||
// On the first iteration only, check to see if rounding up gives the exact result as the
|
||||
// nines may infinitely repeat.
|
||||
round(t, pr + 1, 0);
|
||||
|
||||
if (t.times(t).eq(x)) {
|
||||
r = t;
|
||||
break;
|
||||
}
|
||||
} else if (n != '9999') {
|
||||
break;
|
||||
}
|
||||
|
||||
wpr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
external = true;
|
||||
|
||||
return round(r, pr);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal times `y`, truncated to
|
||||
* `precision` significant digits.
|
||||
*
|
||||
*/
|
||||
P.times = P.mul = function (y) {
|
||||
var carry, e, i, k, r, rL, t, xdL, ydL,
|
||||
x = this,
|
||||
Ctor = x.constructor,
|
||||
xd = x.d,
|
||||
yd = (y = new Ctor(y)).d;
|
||||
|
||||
// Return 0 if either is 0.
|
||||
if (!x.s || !y.s) return new Ctor(0);
|
||||
|
||||
y.s *= x.s;
|
||||
e = x.e + y.e;
|
||||
xdL = xd.length;
|
||||
ydL = yd.length;
|
||||
|
||||
// Ensure xd points to the longer array.
|
||||
if (xdL < ydL) {
|
||||
r = xd;
|
||||
xd = yd;
|
||||
yd = r;
|
||||
rL = xdL;
|
||||
xdL = ydL;
|
||||
ydL = rL;
|
||||
}
|
||||
|
||||
// Initialise the result array with zeros.
|
||||
r = [];
|
||||
rL = xdL + ydL;
|
||||
for (i = rL; i--;) r.push(0);
|
||||
|
||||
// Multiply!
|
||||
for (i = ydL; --i >= 0;) {
|
||||
carry = 0;
|
||||
for (k = xdL + i; k > i;) {
|
||||
t = r[k] + yd[i] * xd[k - i - 1] + carry;
|
||||
r[k--] = t % BASE | 0;
|
||||
carry = t / BASE | 0;
|
||||
}
|
||||
|
||||
r[k] = (r[k] + carry) % BASE | 0;
|
||||
}
|
||||
|
||||
// Remove trailing zeros.
|
||||
for (; !r[--rL];) r.pop();
|
||||
|
||||
if (carry) ++e;
|
||||
else r.shift();
|
||||
|
||||
y.d = r;
|
||||
y.e = e;
|
||||
|
||||
return external ? round(y, Ctor.precision) : y;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp`
|
||||
* decimal places using rounding mode `rm` or `rounding` if `rm` is omitted.
|
||||
*
|
||||
* If `dp` is omitted, return a new Decimal whose value is the value of this Decimal.
|
||||
*
|
||||
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
P.toDecimalPlaces = P.todp = function (dp, rm) {
|
||||
var x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
x = new Ctor(x);
|
||||
if (dp === void 0) return x;
|
||||
|
||||
checkInt32(dp, 0, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
|
||||
return round(x, dp + getBase10Exponent(x) + 1, rm);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a string representing the value of this Decimal in exponential notation rounded to
|
||||
* `dp` fixed decimal places using rounding mode `rounding`.
|
||||
*
|
||||
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
P.toExponential = function (dp, rm) {
|
||||
var str,
|
||||
x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
if (dp === void 0) {
|
||||
str = toString(x, true);
|
||||
} else {
|
||||
checkInt32(dp, 0, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
|
||||
x = round(new Ctor(x), dp + 1, rm);
|
||||
str = toString(x, true, dp + 1);
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a string representing the value of this Decimal in normal (fixed-point) notation to
|
||||
* `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is
|
||||
* omitted.
|
||||
*
|
||||
* As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'.
|
||||
*
|
||||
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
* (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'.
|
||||
* (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'.
|
||||
* (-0).toFixed(3) is '0.000'.
|
||||
* (-0.5).toFixed(0) is '-0'.
|
||||
*
|
||||
*/
|
||||
P.toFixed = function (dp, rm) {
|
||||
var str, y,
|
||||
x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
if (dp === void 0) return toString(x);
|
||||
|
||||
checkInt32(dp, 0, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
|
||||
y = round(new Ctor(x), dp + getBase10Exponent(x) + 1, rm);
|
||||
str = toString(y.abs(), false, dp + getBase10Exponent(y) + 1);
|
||||
|
||||
// To determine whether to add the minus sign look at the value before it was rounded,
|
||||
// i.e. look at `x` rather than `y`.
|
||||
return x.isneg() && !x.isZero() ? '-' + str : str;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a whole number using
|
||||
* rounding mode `rounding`.
|
||||
*
|
||||
*/
|
||||
P.toInteger = P.toint = function () {
|
||||
var x = this,
|
||||
Ctor = x.constructor;
|
||||
return round(new Ctor(x), getBase10Exponent(x) + 1, Ctor.rounding);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return the value of this Decimal converted to a number primitive.
|
||||
*
|
||||
*/
|
||||
P.toNumber = function () {
|
||||
return +this;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal raised to the power `y`,
|
||||
* truncated to `precision` significant digits.
|
||||
*
|
||||
* For non-integer or very large exponents pow(x, y) is calculated using
|
||||
*
|
||||
* x^y = exp(y*ln(x))
|
||||
*
|
||||
* The maximum error is 1 ulp (unit in last place).
|
||||
*
|
||||
* y {number|string|Decimal} The power to which to raise this Decimal.
|
||||
*
|
||||
*/
|
||||
P.toPower = P.pow = function (y) {
|
||||
var e, k, pr, r, sign, yIsInt,
|
||||
x = this,
|
||||
Ctor = x.constructor,
|
||||
guard = 12,
|
||||
yn = +(y = new Ctor(y));
|
||||
|
||||
// pow(x, 0) = 1
|
||||
if (!y.s) return new Ctor(ONE);
|
||||
|
||||
x = new Ctor(x);
|
||||
|
||||
// pow(0, y > 0) = 0
|
||||
// pow(0, y < 0) = Infinity
|
||||
if (!x.s) {
|
||||
if (y.s < 1) throw Error(decimalError + 'Infinity');
|
||||
return x;
|
||||
}
|
||||
|
||||
// pow(1, y) = 1
|
||||
if (x.eq(ONE)) return x;
|
||||
|
||||
pr = Ctor.precision;
|
||||
|
||||
// pow(x, 1) = x
|
||||
if (y.eq(ONE)) return round(x, pr);
|
||||
|
||||
e = y.e;
|
||||
k = y.d.length - 1;
|
||||
yIsInt = e >= k;
|
||||
sign = x.s;
|
||||
|
||||
if (!yIsInt) {
|
||||
|
||||
// pow(x < 0, y non-integer) = NaN
|
||||
if (sign < 0) throw Error(decimalError + 'NaN');
|
||||
|
||||
// If y is a small integer use the 'exponentiation by squaring' algorithm.
|
||||
} else if ((k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) {
|
||||
r = new Ctor(ONE);
|
||||
|
||||
// Max k of 9007199254740991 takes 53 loop iterations.
|
||||
// Maximum digits array length; leaves [28, 34] guard digits.
|
||||
e = Math.ceil(pr / LOG_BASE + 4);
|
||||
|
||||
external = false;
|
||||
|
||||
for (;;) {
|
||||
if (k % 2) {
|
||||
r = r.times(x);
|
||||
truncate(r.d, e);
|
||||
}
|
||||
|
||||
k = mathfloor(k / 2);
|
||||
if (k === 0) break;
|
||||
|
||||
x = x.times(x);
|
||||
truncate(x.d, e);
|
||||
}
|
||||
|
||||
external = true;
|
||||
|
||||
return y.s < 0 ? new Ctor(ONE).div(r) : round(r, pr);
|
||||
}
|
||||
|
||||
// Result is negative if x is negative and the last digit of integer y is odd.
|
||||
sign = sign < 0 && y.d[Math.max(e, k)] & 1 ? -1 : 1;
|
||||
|
||||
x.s = 1;
|
||||
external = false;
|
||||
r = y.times(ln(x, pr + guard));
|
||||
external = true;
|
||||
r = exp(r);
|
||||
r.s = sign;
|
||||
|
||||
return r;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a string representing the value of this Decimal rounded to `sd` significant digits
|
||||
* using rounding mode `rounding`.
|
||||
*
|
||||
* Return 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} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
P.toPrecision = function (sd, rm) {
|
||||
var e, str,
|
||||
x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
if (sd === void 0) {
|
||||
e = getBase10Exponent(x);
|
||||
str = toString(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos);
|
||||
} else {
|
||||
checkInt32(sd, 1, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
|
||||
x = round(new Ctor(x), sd, rm);
|
||||
e = getBase10Exponent(x);
|
||||
str = toString(x, sd <= e || e <= Ctor.toExpNeg, sd);
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd`
|
||||
* significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if
|
||||
* omitted.
|
||||
*
|
||||
* [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||
*
|
||||
*/
|
||||
P.toSignificantDigits = P.tosd = function (sd, rm) {
|
||||
var x = this,
|
||||
Ctor = x.constructor;
|
||||
|
||||
if (sd === void 0) {
|
||||
sd = Ctor.precision;
|
||||
rm = Ctor.rounding;
|
||||
} else {
|
||||
checkInt32(sd, 1, MAX_DIGITS);
|
||||
|
||||
if (rm === void 0) rm = Ctor.rounding;
|
||||
else checkInt32(rm, 0, 8);
|
||||
}
|
||||
|
||||
return round(new Ctor(x), sd, rm);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a string representing the value of this Decimal.
|
||||
*
|
||||
* Return exponential notation if this Decimal has a positive exponent equal to or greater than
|
||||
* `toExpPos`, or a negative exponent equal to or less than `toExpNeg`.
|
||||
*
|
||||
*/
|
||||
P.toString = P.valueOf = P.val = P.toJSON = P[Symbol.for('nodejs.util.inspect.custom')] = function () {
|
||||
var x = this,
|
||||
e = getBase10Exponent(x),
|
||||
Ctor = x.constructor;
|
||||
|
||||
return toString(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos);
|
||||
};
|
||||
|
||||
|
||||
// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers.
|
||||
|
||||
|
||||
/*
|
||||
* add P.minus, P.plus
|
||||
* checkInt32 P.todp, P.toExponential, P.toFixed, P.toPrecision, P.tosd
|
||||
* digitsToString P.log, P.sqrt, P.pow, toString, exp, ln
|
||||
* divide P.div, P.idiv, P.log, P.mod, P.sqrt, exp, ln
|
||||
* exp P.exp, P.pow
|
||||
* getBase10Exponent P.exponent, P.sd, P.toint, P.sqrt, P.todp, P.toFixed, P.toPrecision,
|
||||
* P.toString, divide, round, toString, exp, ln
|
||||
* getLn10 P.log, ln
|
||||
* getZeroString digitsToString, toString
|
||||
* ln P.log, P.ln, P.pow, exp
|
||||
* parseDecimal Decimal
|
||||
* round P.abs, P.idiv, P.log, P.minus, P.mod, P.neg, P.plus, P.toint, P.sqrt,
|
||||
* P.times, P.todp, P.toExponential, P.toFixed, P.pow, P.toPrecision, P.tosd,
|
||||
* divide, getLn10, exp, ln
|
||||
* subtract P.minus, P.plus
|
||||
* toString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf
|
||||
* truncate P.pow
|
||||
*
|
||||
* Throws: P.log, P.mod, P.sd, P.sqrt, P.pow, checkInt32, divide, round,
|
||||
* getLn10, exp, ln, parseDecimal, Decimal, config
|
||||
*/
|
||||
|
||||
|
||||
function add(x, y) {
|
||||
var carry, d, e, i, k, len, xd, yd,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
// If either is zero...
|
||||
if (!x.s || !y.s) {
|
||||
|
||||
// Return x if y is zero.
|
||||
// Return y if y is non-zero.
|
||||
if (!y.s) y = new Ctor(x);
|
||||
return external ? round(y, pr) : y;
|
||||
}
|
||||
|
||||
xd = x.d;
|
||||
yd = y.d;
|
||||
|
||||
// x and y are finite, non-zero numbers with the same sign.
|
||||
|
||||
k = x.e;
|
||||
e = y.e;
|
||||
xd = xd.slice();
|
||||
i = k - e;
|
||||
|
||||
// If base 1e7 exponents differ...
|
||||
if (i) {
|
||||
if (i < 0) {
|
||||
d = xd;
|
||||
i = -i;
|
||||
len = yd.length;
|
||||
} else {
|
||||
d = yd;
|
||||
e = k;
|
||||
len = xd.length;
|
||||
}
|
||||
|
||||
// Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1.
|
||||
k = Math.ceil(pr / LOG_BASE);
|
||||
len = k > len ? k + 1 : len + 1;
|
||||
|
||||
if (i > len) {
|
||||
i = len;
|
||||
d.length = 1;
|
||||
}
|
||||
|
||||
// Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts.
|
||||
d.reverse();
|
||||
for (; i--;) d.push(0);
|
||||
d.reverse();
|
||||
}
|
||||
|
||||
len = xd.length;
|
||||
i = yd.length;
|
||||
|
||||
// If yd is longer than xd, swap xd and yd so xd points to the longer array.
|
||||
if (len - i < 0) {
|
||||
i = len;
|
||||
d = yd;
|
||||
yd = xd;
|
||||
xd = d;
|
||||
}
|
||||
|
||||
// Only start adding at yd.length - 1 as the further digits of xd can be left as they are.
|
||||
for (carry = 0; i;) {
|
||||
carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0;
|
||||
xd[i] %= BASE;
|
||||
}
|
||||
|
||||
if (carry) {
|
||||
xd.unshift(carry);
|
||||
++e;
|
||||
}
|
||||
|
||||
// Remove trailing zeros.
|
||||
// No need to check for zero, as +x + +y != 0 && -x + -y != 0
|
||||
for (len = xd.length; xd[--len] == 0;) xd.pop();
|
||||
|
||||
y.d = xd;
|
||||
y.e = e;
|
||||
|
||||
return external ? round(y, pr) : y;
|
||||
}
|
||||
|
||||
|
||||
function checkInt32(i, min, max) {
|
||||
if (i !== ~~i || i < min || i > max) {
|
||||
throw Error(invalidArgument + i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function digitsToString(d) {
|
||||
var i, k, ws,
|
||||
indexOfLastWord = d.length - 1,
|
||||
str = '',
|
||||
w = d[0];
|
||||
|
||||
if (indexOfLastWord > 0) {
|
||||
str += w;
|
||||
for (i = 1; i < indexOfLastWord; i++) {
|
||||
ws = d[i] + '';
|
||||
k = LOG_BASE - ws.length;
|
||||
if (k) str += getZeroString(k);
|
||||
str += ws;
|
||||
}
|
||||
|
||||
w = d[i];
|
||||
ws = w + '';
|
||||
k = LOG_BASE - ws.length;
|
||||
if (k) str += getZeroString(k);
|
||||
} else if (w === 0) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// Remove trailing zeros of last w.
|
||||
for (; w % 10 === 0;) w /= 10;
|
||||
|
||||
return str + w;
|
||||
}
|
||||
|
||||
|
||||
var divide = (function () {
|
||||
|
||||
// Assumes non-zero x and k, and hence non-zero result.
|
||||
function multiplyInteger(x, k) {
|
||||
var temp,
|
||||
carry = 0,
|
||||
i = x.length;
|
||||
|
||||
for (x = x.slice(); i--;) {
|
||||
temp = x[i] * k + carry;
|
||||
x[i] = temp % BASE | 0;
|
||||
carry = temp / BASE | 0;
|
||||
}
|
||||
|
||||
if (carry) x.unshift(carry);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
function compare(a, b, aL, bL) {
|
||||
var i, r;
|
||||
|
||||
if (aL != bL) {
|
||||
r = aL > bL ? 1 : -1;
|
||||
} else {
|
||||
for (i = r = 0; i < aL; i++) {
|
||||
if (a[i] != b[i]) {
|
||||
r = a[i] > b[i] ? 1 : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
function subtract(a, b, aL) {
|
||||
var i = 0;
|
||||
|
||||
// Subtract b from a.
|
||||
for (; aL--;) {
|
||||
a[aL] -= i;
|
||||
i = a[aL] < b[aL] ? 1 : 0;
|
||||
a[aL] = i * BASE + a[aL] - b[aL];
|
||||
}
|
||||
|
||||
// Remove leading zeros.
|
||||
for (; !a[0] && a.length > 1;) a.shift();
|
||||
}
|
||||
|
||||
return function (x, y, pr, dp) {
|
||||
var cmp, e, i, k, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, yL, yz,
|
||||
Ctor = x.constructor,
|
||||
sign = x.s == y.s ? 1 : -1,
|
||||
xd = x.d,
|
||||
yd = y.d;
|
||||
|
||||
// Either 0?
|
||||
if (!x.s) return new Ctor(x);
|
||||
if (!y.s) throw Error(decimalError + 'Division by zero');
|
||||
|
||||
e = x.e - y.e;
|
||||
yL = yd.length;
|
||||
xL = xd.length;
|
||||
q = new Ctor(sign);
|
||||
qd = q.d = [];
|
||||
|
||||
// Result exponent may be one less than e.
|
||||
for (i = 0; yd[i] == (xd[i] || 0); ) ++i;
|
||||
if (yd[i] > (xd[i] || 0)) --e;
|
||||
|
||||
if (pr == null) {
|
||||
sd = pr = Ctor.precision;
|
||||
} else if (dp) {
|
||||
sd = pr + (getBase10Exponent(x) - getBase10Exponent(y)) + 1;
|
||||
} else {
|
||||
sd = pr;
|
||||
}
|
||||
|
||||
if (sd < 0) return new Ctor(0);
|
||||
|
||||
// Convert precision in number of base 10 digits to base 1e7 digits.
|
||||
sd = sd / LOG_BASE + 2 | 0;
|
||||
i = 0;
|
||||
|
||||
// divisor < 1e7
|
||||
if (yL == 1) {
|
||||
k = 0;
|
||||
yd = yd[0];
|
||||
sd++;
|
||||
|
||||
// k is the carry.
|
||||
for (; (i < xL || k) && sd--; i++) {
|
||||
t = k * BASE + (xd[i] || 0);
|
||||
qd[i] = t / yd | 0;
|
||||
k = t % yd | 0;
|
||||
}
|
||||
|
||||
// divisor >= 1e7
|
||||
} else {
|
||||
|
||||
// Normalise xd and yd so highest order digit of yd is >= BASE/2
|
||||
k = BASE / (yd[0] + 1) | 0;
|
||||
|
||||
if (k > 1) {
|
||||
yd = multiplyInteger(yd, k);
|
||||
xd = multiplyInteger(xd, k);
|
||||
yL = yd.length;
|
||||
xL = xd.length;
|
||||
}
|
||||
|
||||
xi = yL;
|
||||
rem = xd.slice(0, yL);
|
||||
remL = rem.length;
|
||||
|
||||
// Add zeros to make remainder as long as divisor.
|
||||
for (; remL < yL;) rem[remL++] = 0;
|
||||
|
||||
yz = yd.slice();
|
||||
yz.unshift(0);
|
||||
yd0 = yd[0];
|
||||
|
||||
if (yd[1] >= BASE / 2) ++yd0;
|
||||
|
||||
do {
|
||||
k = 0;
|
||||
|
||||
// Compare divisor and remainder.
|
||||
cmp = compare(yd, rem, yL, remL);
|
||||
|
||||
// If divisor < remainder.
|
||||
if (cmp < 0) {
|
||||
|
||||
// Calculate trial digit, k.
|
||||
rem0 = rem[0];
|
||||
if (yL != remL) rem0 = rem0 * BASE + (rem[1] || 0);
|
||||
|
||||
// k will be how many times the divisor goes into the current remainder.
|
||||
k = rem0 / yd0 | 0;
|
||||
|
||||
// Algorithm:
|
||||
// 1. product = divisor * trial digit (k)
|
||||
// 2. if product > remainder: product -= divisor, k--
|
||||
// 3. remainder -= product
|
||||
// 4. if product was < remainder at 2:
|
||||
// 5. compare new remainder and divisor
|
||||
// 6. If remainder > divisor: remainder -= divisor, k++
|
||||
|
||||
if (k > 1) {
|
||||
if (k >= BASE) k = BASE - 1;
|
||||
|
||||
// product = divisor * trial digit.
|
||||
prod = multiplyInteger(yd, k);
|
||||
prodL = prod.length;
|
||||
remL = rem.length;
|
||||
|
||||
// Compare product and remainder.
|
||||
cmp = compare(prod, rem, prodL, remL);
|
||||
|
||||
// product > remainder.
|
||||
if (cmp == 1) {
|
||||
k--;
|
||||
|
||||
// Subtract divisor from product.
|
||||
subtract(prod, yL < prodL ? yz : yd, prodL);
|
||||
}
|
||||
} else {
|
||||
|
||||
// cmp is -1.
|
||||
// If k is 0, there is no need to compare yd and rem again below, so change cmp to 1
|
||||
// to avoid it. If k is 1 there is a need to compare yd and rem again below.
|
||||
if (k == 0) cmp = k = 1;
|
||||
prod = yd.slice();
|
||||
}
|
||||
|
||||
prodL = prod.length;
|
||||
if (prodL < remL) prod.unshift(0);
|
||||
|
||||
// Subtract product from remainder.
|
||||
subtract(rem, prod, remL);
|
||||
|
||||
// If product was < previous remainder.
|
||||
if (cmp == -1) {
|
||||
remL = rem.length;
|
||||
|
||||
// Compare divisor and new remainder.
|
||||
cmp = compare(yd, rem, yL, remL);
|
||||
|
||||
// If divisor < new remainder, subtract divisor from remainder.
|
||||
if (cmp < 1) {
|
||||
k++;
|
||||
|
||||
// Subtract divisor from remainder.
|
||||
subtract(rem, yL < remL ? yz : yd, remL);
|
||||
}
|
||||
}
|
||||
|
||||
remL = rem.length;
|
||||
} else if (cmp === 0) {
|
||||
k++;
|
||||
rem = [0];
|
||||
} // if cmp === 1, k will be 0
|
||||
|
||||
// Add the next digit, k, to the result array.
|
||||
qd[i++] = k;
|
||||
|
||||
// Update the remainder.
|
||||
if (cmp && rem[0]) {
|
||||
rem[remL++] = xd[xi] || 0;
|
||||
} else {
|
||||
rem = [xd[xi]];
|
||||
remL = 1;
|
||||
}
|
||||
|
||||
} while ((xi++ < xL || rem[0] !== void 0) && sd--);
|
||||
}
|
||||
|
||||
// Leading zero?
|
||||
if (!qd[0]) qd.shift();
|
||||
|
||||
q.e = e;
|
||||
|
||||
return round(q, dp ? pr + getBase10Exponent(q) + 1 : pr);
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the natural exponential of `x` truncated to `sd`
|
||||
* significant digits.
|
||||
*
|
||||
* Taylor/Maclaurin series.
|
||||
*
|
||||
* exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ...
|
||||
*
|
||||
* Argument reduction:
|
||||
* Repeat x = x / 32, k += 5, until |x| < 0.1
|
||||
* exp(x) = exp(x / 2^k)^(2^k)
|
||||
*
|
||||
* Previously, the argument was initially reduced by
|
||||
* exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10)
|
||||
* to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was
|
||||
* found to be slower than just dividing repeatedly by 32 as above.
|
||||
*
|
||||
* (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324)
|
||||
*
|
||||
* exp(x) is non-terminating for any finite, non-zero x.
|
||||
*
|
||||
*/
|
||||
function exp(x, sd) {
|
||||
var denominator, guard, pow, sum, t, wpr,
|
||||
i = 0,
|
||||
k = 0,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
if (getBase10Exponent(x) > 16) throw Error(exponentOutOfRange + getBase10Exponent(x));
|
||||
|
||||
// exp(0) = 1
|
||||
if (!x.s) return new Ctor(ONE);
|
||||
|
||||
if (sd == null) {
|
||||
external = false;
|
||||
wpr = pr;
|
||||
} else {
|
||||
wpr = sd;
|
||||
}
|
||||
|
||||
t = new Ctor(0.03125);
|
||||
|
||||
while (x.abs().gte(0.1)) {
|
||||
x = x.times(t); // x = x / 2^5
|
||||
k += 5;
|
||||
}
|
||||
|
||||
// Estimate the precision increase necessary to ensure the first 4 rounding digits are correct.
|
||||
guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0;
|
||||
wpr += guard;
|
||||
denominator = pow = sum = new Ctor(ONE);
|
||||
Ctor.precision = wpr;
|
||||
|
||||
for (;;) {
|
||||
pow = round(pow.times(x), wpr);
|
||||
denominator = denominator.times(++i);
|
||||
t = sum.plus(divide(pow, denominator, wpr));
|
||||
|
||||
if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {
|
||||
while (k--) sum = round(sum.times(sum), wpr);
|
||||
Ctor.precision = pr;
|
||||
return sd == null ? (external = true, round(sum, pr)) : sum;
|
||||
}
|
||||
|
||||
sum = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate the base 10 exponent from the base 1e7 exponent.
|
||||
function getBase10Exponent(x) {
|
||||
var e = x.e * LOG_BASE,
|
||||
w = x.d[0];
|
||||
|
||||
// Add the number of digits of the first word of the digits array.
|
||||
for (; w >= 10; w /= 10) e++;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
function getLn10(Ctor, sd, pr) {
|
||||
|
||||
if (sd > Ctor.LN10.sd()) {
|
||||
|
||||
|
||||
// Reset global state in case the exception is caught.
|
||||
external = true;
|
||||
if (pr) Ctor.precision = pr;
|
||||
throw Error(decimalError + 'LN10 precision limit exceeded');
|
||||
}
|
||||
|
||||
return round(new Ctor(Ctor.LN10), sd);
|
||||
}
|
||||
|
||||
|
||||
function getZeroString(k) {
|
||||
var zs = '';
|
||||
for (; k--;) zs += '0';
|
||||
return zs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a new Decimal whose value is the natural logarithm of `x` truncated to `sd` significant
|
||||
* digits.
|
||||
*
|
||||
* ln(n) is non-terminating (n != 1)
|
||||
*
|
||||
*/
|
||||
function ln(y, sd) {
|
||||
var c, c0, denominator, e, numerator, sum, t, wpr, x2,
|
||||
n = 1,
|
||||
guard = 10,
|
||||
x = y,
|
||||
xd = x.d,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
// ln(-x) = NaN
|
||||
// ln(0) = -Infinity
|
||||
if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity'));
|
||||
|
||||
// ln(1) = 0
|
||||
if (x.eq(ONE)) return new Ctor(0);
|
||||
|
||||
if (sd == null) {
|
||||
external = false;
|
||||
wpr = pr;
|
||||
} else {
|
||||
wpr = sd;
|
||||
}
|
||||
|
||||
if (x.eq(10)) {
|
||||
if (sd == null) external = true;
|
||||
return getLn10(Ctor, wpr);
|
||||
}
|
||||
|
||||
wpr += guard;
|
||||
Ctor.precision = wpr;
|
||||
c = digitsToString(xd);
|
||||
c0 = c.charAt(0);
|
||||
e = getBase10Exponent(x);
|
||||
|
||||
if (Math.abs(e) < 1.5e15) {
|
||||
|
||||
// Argument reduction.
|
||||
// The series converges faster the closer the argument is to 1, so using
|
||||
// ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b
|
||||
// multiply the argument by itself until the leading digits of the significand are 7, 8, 9,
|
||||
// 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can
|
||||
// later be divided by this number, then separate out the power of 10 using
|
||||
// ln(a*10^b) = ln(a) + b*ln(10).
|
||||
|
||||
// max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14).
|
||||
//while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) {
|
||||
// max n is 6 (gives 0.7 - 1.3)
|
||||
while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) {
|
||||
x = x.times(y);
|
||||
c = digitsToString(x.d);
|
||||
c0 = c.charAt(0);
|
||||
n++;
|
||||
}
|
||||
|
||||
e = getBase10Exponent(x);
|
||||
|
||||
if (c0 > 1) {
|
||||
x = new Ctor('0.' + c);
|
||||
e++;
|
||||
} else {
|
||||
x = new Ctor(c0 + '.' + c.slice(1));
|
||||
}
|
||||
} else {
|
||||
|
||||
// The argument reduction method above may result in overflow if the argument y is a massive
|
||||
// number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this
|
||||
// function using ln(x*10^e) = ln(x) + e*ln(10).
|
||||
t = getLn10(Ctor, wpr + 2, pr).times(e + '');
|
||||
x = ln(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t);
|
||||
|
||||
Ctor.precision = pr;
|
||||
return sd == null ? (external = true, round(x, pr)) : x;
|
||||
}
|
||||
|
||||
// x is reduced to a value near 1.
|
||||
|
||||
// Taylor series.
|
||||
// ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...)
|
||||
// where x = (y - 1)/(y + 1) (|x| < 1)
|
||||
sum = numerator = x = divide(x.minus(ONE), x.plus(ONE), wpr);
|
||||
x2 = round(x.times(x), wpr);
|
||||
denominator = 3;
|
||||
|
||||
for (;;) {
|
||||
numerator = round(numerator.times(x2), wpr);
|
||||
t = sum.plus(divide(numerator, new Ctor(denominator), wpr));
|
||||
|
||||
if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {
|
||||
sum = sum.times(2);
|
||||
|
||||
// Reverse the argument reduction.
|
||||
if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + ''));
|
||||
sum = divide(sum, new Ctor(n), wpr);
|
||||
|
||||
Ctor.precision = pr;
|
||||
return sd == null ? (external = true, round(sum, pr)) : sum;
|
||||
}
|
||||
|
||||
sum = t;
|
||||
denominator += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse the value of a new Decimal `x` from string `str`.
|
||||
*/
|
||||
function parseDecimal(x, str) {
|
||||
var e, i, len;
|
||||
|
||||
// Decimal point?
|
||||
if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
|
||||
|
||||
// Exponential form?
|
||||
if ((i = str.search(/e/i)) > 0) {
|
||||
|
||||
// Determine exponent.
|
||||
if (e < 0) e = i;
|
||||
e += +str.slice(i + 1);
|
||||
str = str.substring(0, i);
|
||||
} else if (e < 0) {
|
||||
|
||||
// Integer.
|
||||
e = str.length;
|
||||
}
|
||||
|
||||
// Determine leading zeros.
|
||||
for (i = 0; str.charCodeAt(i) === 48;) ++i;
|
||||
|
||||
// Determine trailing zeros.
|
||||
for (len = str.length; str.charCodeAt(len - 1) === 48;) --len;
|
||||
str = str.slice(i, len);
|
||||
|
||||
if (str) {
|
||||
len -= i;
|
||||
e = e - i - 1;
|
||||
x.e = mathfloor(e / LOG_BASE);
|
||||
x.d = [];
|
||||
|
||||
// Transform base
|
||||
|
||||
// e is the base 10 exponent.
|
||||
// i is where to slice str to get the first word of the digits array.
|
||||
i = (e + 1) % LOG_BASE;
|
||||
if (e < 0) i += LOG_BASE;
|
||||
|
||||
if (i < len) {
|
||||
if (i) x.d.push(+str.slice(0, i));
|
||||
for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE));
|
||||
str = str.slice(i);
|
||||
i = LOG_BASE - str.length;
|
||||
} else {
|
||||
i -= len;
|
||||
}
|
||||
|
||||
for (; i--;) str += '0';
|
||||
x.d.push(+str);
|
||||
|
||||
if (external && (x.e > MAX_E || x.e < -MAX_E)) throw Error(exponentOutOfRange + e);
|
||||
} else {
|
||||
|
||||
// Zero.
|
||||
x.s = 0;
|
||||
x.e = 0;
|
||||
x.d = [0];
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Round `x` to `sd` significant digits, using rounding mode `rm` if present (truncate otherwise).
|
||||
*/
|
||||
function round(x, sd, rm) {
|
||||
var i, j, k, n, rd, doRound, w, xdi,
|
||||
xd = x.d;
|
||||
|
||||
// rd: the rounding digit, i.e. the digit after the digit that may be rounded up.
|
||||
// w: the word of xd which contains the rounding digit, a base 1e7 number.
|
||||
// xdi: the index of w within xd.
|
||||
// n: the number of digits of w.
|
||||
// i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if
|
||||
// they had leading zeros)
|
||||
// j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero).
|
||||
|
||||
// Get the length of the first word of the digits array xd.
|
||||
for (n = 1, k = xd[0]; k >= 10; k /= 10) n++;
|
||||
i = sd - n;
|
||||
|
||||
// Is the rounding digit in the first word of xd?
|
||||
if (i < 0) {
|
||||
i += LOG_BASE;
|
||||
j = sd;
|
||||
w = xd[xdi = 0];
|
||||
} else {
|
||||
xdi = Math.ceil((i + 1) / LOG_BASE);
|
||||
k = xd.length;
|
||||
if (xdi >= k) return x;
|
||||
w = k = xd[xdi];
|
||||
|
||||
// Get the number of digits of w.
|
||||
for (n = 1; k >= 10; k /= 10) n++;
|
||||
|
||||
// Get the index of rd within w.
|
||||
i %= LOG_BASE;
|
||||
|
||||
// Get the index of rd within w, adjusted for leading zeros.
|
||||
// The number of leading zeros of w is given by LOG_BASE - n.
|
||||
j = i - LOG_BASE + n;
|
||||
}
|
||||
|
||||
if (rm !== void 0) {
|
||||
k = mathpow(10, n - j - 1);
|
||||
|
||||
// Get the rounding digit at index j of w.
|
||||
rd = w / k % 10 | 0;
|
||||
|
||||
// Are there any non-zero digits after the rounding digit?
|
||||
doRound = sd < 0 || xd[xdi + 1] !== void 0 || w % k;
|
||||
|
||||
// The expression `w % mathpow(10, n - j - 1)` returns all the digits of w to the right of the
|
||||
// digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression will give
|
||||
// 714.
|
||||
|
||||
doRound = rm < 4
|
||||
? (rd || doRound) && (rm == 0 || rm == (x.s < 0 ? 3 : 2))
|
||||
: rd > 5 || rd == 5 && (rm == 4 || doRound || rm == 6 &&
|
||||
|
||||
// Check whether the digit to the left of the rounding digit is odd.
|
||||
((i > 0 ? j > 0 ? w / mathpow(10, n - j) : 0 : xd[xdi - 1]) % 10) & 1 ||
|
||||
rm == (x.s < 0 ? 8 : 7));
|
||||
}
|
||||
|
||||
if (sd < 1 || !xd[0]) {
|
||||
if (doRound) {
|
||||
k = getBase10Exponent(x);
|
||||
xd.length = 1;
|
||||
|
||||
// Convert sd to decimal places.
|
||||
sd = sd - k - 1;
|
||||
|
||||
// 1, 0.1, 0.01, 0.001, 0.0001 etc.
|
||||
xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE);
|
||||
x.e = mathfloor(-sd / LOG_BASE) || 0;
|
||||
} else {
|
||||
xd.length = 1;
|
||||
|
||||
// Zero.
|
||||
xd[0] = x.e = x.s = 0;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// Remove excess digits.
|
||||
if (i == 0) {
|
||||
xd.length = xdi;
|
||||
k = 1;
|
||||
xdi--;
|
||||
} else {
|
||||
xd.length = xdi + 1;
|
||||
k = mathpow(10, LOG_BASE - i);
|
||||
|
||||
// E.g. 56700 becomes 56000 if 7 is the rounding digit.
|
||||
// j > 0 means i > number of leading zeros of w.
|
||||
xd[xdi] = j > 0 ? (w / mathpow(10, n - j) % mathpow(10, j) | 0) * k : 0;
|
||||
}
|
||||
|
||||
if (doRound) {
|
||||
for (;;) {
|
||||
|
||||
// Is the digit to be rounded up in the first word of xd?
|
||||
if (xdi == 0) {
|
||||
if ((xd[0] += k) == BASE) {
|
||||
xd[0] = 1;
|
||||
++x.e;
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
xd[xdi] += k;
|
||||
if (xd[xdi] != BASE) break;
|
||||
xd[xdi--] = 0;
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove trailing zeros.
|
||||
for (i = xd.length; xd[--i] === 0;) xd.pop();
|
||||
|
||||
if (external && (x.e > MAX_E || x.e < -MAX_E)) {
|
||||
throw Error(exponentOutOfRange + getBase10Exponent(x));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
function subtract(x, y) {
|
||||
var d, e, i, j, k, len, xd, xe, xLTy, yd,
|
||||
Ctor = x.constructor,
|
||||
pr = Ctor.precision;
|
||||
|
||||
// Return y negated if x is zero.
|
||||
// Return x if y is zero and x is non-zero.
|
||||
if (!x.s || !y.s) {
|
||||
if (y.s) y.s = -y.s;
|
||||
else y = new Ctor(x);
|
||||
return external ? round(y, pr) : y;
|
||||
}
|
||||
|
||||
xd = x.d;
|
||||
yd = y.d;
|
||||
|
||||
// x and y are non-zero numbers with the same sign.
|
||||
|
||||
e = y.e;
|
||||
xe = x.e;
|
||||
xd = xd.slice();
|
||||
k = xe - e;
|
||||
|
||||
// If exponents differ...
|
||||
if (k) {
|
||||
xLTy = k < 0;
|
||||
|
||||
if (xLTy) {
|
||||
d = xd;
|
||||
k = -k;
|
||||
len = yd.length;
|
||||
} else {
|
||||
d = yd;
|
||||
e = xe;
|
||||
len = xd.length;
|
||||
}
|
||||
|
||||
// Numbers with massively different exponents would result in a very high number of zeros
|
||||
// needing to be prepended, but this can be avoided while still ensuring correct rounding by
|
||||
// limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`.
|
||||
i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2;
|
||||
|
||||
if (k > i) {
|
||||
k = i;
|
||||
d.length = 1;
|
||||
}
|
||||
|
||||
// Prepend zeros to equalise exponents.
|
||||
d.reverse();
|
||||
for (i = k; i--;) d.push(0);
|
||||
d.reverse();
|
||||
|
||||
// Base 1e7 exponents equal.
|
||||
} else {
|
||||
|
||||
// Check digits to determine which is the bigger number.
|
||||
|
||||
i = xd.length;
|
||||
len = yd.length;
|
||||
xLTy = i < len;
|
||||
if (xLTy) len = i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (xd[i] != yd[i]) {
|
||||
xLTy = xd[i] < yd[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
}
|
||||
|
||||
if (xLTy) {
|
||||
d = xd;
|
||||
xd = yd;
|
||||
yd = d;
|
||||
y.s = -y.s;
|
||||
}
|
||||
|
||||
len = xd.length;
|
||||
|
||||
// Append zeros to xd if shorter.
|
||||
// Don't add zeros to yd if shorter as subtraction only needs to start at yd length.
|
||||
for (i = yd.length - len; i > 0; --i) xd[len++] = 0;
|
||||
|
||||
// Subtract yd from xd.
|
||||
for (i = yd.length; i > k;) {
|
||||
if (xd[--i] < yd[i]) {
|
||||
for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1;
|
||||
--xd[j];
|
||||
xd[i] += BASE;
|
||||
}
|
||||
|
||||
xd[i] -= yd[i];
|
||||
}
|
||||
|
||||
// Remove trailing zeros.
|
||||
for (; xd[--len] === 0;) xd.pop();
|
||||
|
||||
// Remove leading zeros and adjust exponent accordingly.
|
||||
for (; xd[0] === 0; xd.shift()) --e;
|
||||
|
||||
// Zero?
|
||||
if (!xd[0]) return new Ctor(0);
|
||||
|
||||
y.d = xd;
|
||||
y.e = e;
|
||||
|
||||
//return external && xd.length >= pr / LOG_BASE ? round(y, pr) : y;
|
||||
return external ? round(y, pr) : y;
|
||||
}
|
||||
|
||||
|
||||
function toString(x, isExp, sd) {
|
||||
var k,
|
||||
e = getBase10Exponent(x),
|
||||
str = digitsToString(x.d),
|
||||
len = str.length;
|
||||
|
||||
if (isExp) {
|
||||
if (sd && (k = sd - len) > 0) {
|
||||
str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k);
|
||||
} else if (len > 1) {
|
||||
str = str.charAt(0) + '.' + str.slice(1);
|
||||
}
|
||||
|
||||
str = str + (e < 0 ? 'e' : 'e+') + e;
|
||||
} else if (e < 0) {
|
||||
str = '0.' + getZeroString(-e - 1) + str;
|
||||
if (sd && (k = sd - len) > 0) str += getZeroString(k);
|
||||
} else if (e >= len) {
|
||||
str += getZeroString(e + 1 - len);
|
||||
if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k);
|
||||
} else {
|
||||
if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k);
|
||||
if (sd && (k = sd - len) > 0) {
|
||||
if (e + 1 === len) str += '.';
|
||||
str += getZeroString(k);
|
||||
}
|
||||
}
|
||||
|
||||
return x.s < 0 ? '-' + str : str;
|
||||
}
|
||||
|
||||
|
||||
// Does not strip trailing zeros.
|
||||
function truncate(arr, len) {
|
||||
if (arr.length > len) {
|
||||
arr.length = len;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Decimal methods
|
||||
|
||||
|
||||
/*
|
||||
* clone
|
||||
* config/set
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Create and return a Decimal constructor with the same configuration properties as this Decimal
|
||||
* constructor.
|
||||
*
|
||||
*/
|
||||
function clone(obj) {
|
||||
var i, p, ps;
|
||||
|
||||
/*
|
||||
* The Decimal constructor and exported function.
|
||||
* Return a new Decimal instance.
|
||||
*
|
||||
* value {number|string|Decimal} A numeric value.
|
||||
*
|
||||
*/
|
||||
function Decimal(value) {
|
||||
var x = this;
|
||||
|
||||
// Decimal called without new.
|
||||
if (!(x instanceof Decimal)) return new Decimal(value);
|
||||
|
||||
// Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor
|
||||
// which points to Object.
|
||||
x.constructor = Decimal;
|
||||
|
||||
// Duplicate.
|
||||
if (value instanceof Decimal) {
|
||||
x.s = value.s;
|
||||
x.e = value.e;
|
||||
x.d = (value = value.d) ? value.slice() : value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof value === 'number') {
|
||||
|
||||
// Reject Infinity/NaN.
|
||||
if (value * 0 !== 0) {
|
||||
throw Error(invalidArgument + value);
|
||||
}
|
||||
|
||||
if (value > 0) {
|
||||
x.s = 1;
|
||||
} else if (value < 0) {
|
||||
value = -value;
|
||||
x.s = -1;
|
||||
} else {
|
||||
x.s = 0;
|
||||
x.e = 0;
|
||||
x.d = [0];
|
||||
return;
|
||||
}
|
||||
|
||||
// Fast path for small integers.
|
||||
if (value === ~~value && value < 1e7) {
|
||||
x.e = 0;
|
||||
x.d = [value];
|
||||
return;
|
||||
}
|
||||
|
||||
return parseDecimal(x, value.toString());
|
||||
} else if (typeof value !== 'string') {
|
||||
throw Error(invalidArgument + value);
|
||||
}
|
||||
|
||||
// Minus sign?
|
||||
if (value.charCodeAt(0) === 45) {
|
||||
value = value.slice(1);
|
||||
x.s = -1;
|
||||
} else {
|
||||
x.s = 1;
|
||||
}
|
||||
|
||||
if (isDecimal.test(value)) parseDecimal(x, value);
|
||||
else throw Error(invalidArgument + value);
|
||||
}
|
||||
|
||||
Decimal.prototype = P;
|
||||
|
||||
Decimal.ROUND_UP = 0;
|
||||
Decimal.ROUND_DOWN = 1;
|
||||
Decimal.ROUND_CEIL = 2;
|
||||
Decimal.ROUND_FLOOR = 3;
|
||||
Decimal.ROUND_HALF_UP = 4;
|
||||
Decimal.ROUND_HALF_DOWN = 5;
|
||||
Decimal.ROUND_HALF_EVEN = 6;
|
||||
Decimal.ROUND_HALF_CEIL = 7;
|
||||
Decimal.ROUND_HALF_FLOOR = 8;
|
||||
|
||||
Decimal.clone = clone;
|
||||
Decimal.config = Decimal.set = config;
|
||||
|
||||
if (obj === void 0) obj = {};
|
||||
if (obj) {
|
||||
ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'LN10'];
|
||||
for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p];
|
||||
}
|
||||
|
||||
Decimal.config(obj);
|
||||
|
||||
return Decimal;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Configure global settings for a Decimal constructor.
|
||||
*
|
||||
* `obj` is an object with one or more of the following properties,
|
||||
*
|
||||
* precision {number}
|
||||
* rounding {number}
|
||||
* toExpNeg {number}
|
||||
* toExpPos {number}
|
||||
*
|
||||
* E.g. Decimal.config({ precision: 20, rounding: 4 })
|
||||
*
|
||||
*/
|
||||
function config(obj) {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
throw Error(decimalError + 'Object expected');
|
||||
}
|
||||
var i, p, v,
|
||||
ps = [
|
||||
'precision', 1, MAX_DIGITS,
|
||||
'rounding', 0, 8,
|
||||
'toExpNeg', -1 / 0, 0,
|
||||
'toExpPos', 0, 1 / 0
|
||||
];
|
||||
|
||||
for (i = 0; i < ps.length; i += 3) {
|
||||
if ((v = obj[p = ps[i]]) !== void 0) {
|
||||
if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v;
|
||||
else throw Error(invalidArgument + p + ': ' + v);
|
||||
}
|
||||
}
|
||||
|
||||
if ((v = obj[p = 'LN10']) !== void 0) {
|
||||
if (v == Math.LN10) this[p] = new this(v);
|
||||
else throw Error(invalidArgument + p + ': ' + v);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Create and configure initial Decimal constructor.
|
||||
export var Decimal = clone(defaults);
|
||||
|
||||
// Internal constant.
|
||||
ONE = new Decimal(1);
|
||||
|
||||
export default Decimal;
|
||||
+1312
@@ -0,0 +1,1312 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="Author" content="MMclaughlin">
|
||||
<title>decimal.js-light API</title>
|
||||
<style>
|
||||
html{font-size:100%}
|
||||
body{background:#fff;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;
|
||||
line-height:1.65em;min-height:100%;margin:0}
|
||||
body,i{color:#000}
|
||||
.nav{background:#fff;position:fixed;top:0;bottom:0;left:0;width:210px;overflow-y:auto;
|
||||
padding:15px 0 30px 15px}
|
||||
div.container{width:600px;margin:50px 0 50px 240px}
|
||||
p{margin:0 0 1em;width:600px}
|
||||
pre,ul{margin:1em 0}
|
||||
h1,h2,h3,h4,h5{margin:0;padding:1.5em 0 0}
|
||||
h1,h2{padding:.75em 0}
|
||||
h1{font:400 3em Consolas, monaco, monospace;color:#000;margin-bottom:1em}
|
||||
h2{font-size:2.25em;color:#f00}
|
||||
h3{font-size:1.75em;color:#69d2e7}
|
||||
h4{font-size:1.75em;color:#f00;padding-bottom:.75em}
|
||||
h5{font-size:1.2em;margin-bottom:.4em}
|
||||
h6{font-size:1.1em;margin-bottom:0.8em;padding:0.5em 0}
|
||||
dd dt{font-size:1.2em}
|
||||
dt{padding-top:.5em}
|
||||
dd{padding-top:.35em}
|
||||
b{font-weight:700}
|
||||
a,a:visited{color:#f00;text-decoration:none}
|
||||
a:active,a:hover{outline:0;text-decoration:underline}
|
||||
.nav a,.nav b,.nav a:visited{display:block;color:#f00;font-weight:700;margin-top:15px}
|
||||
.nav b{color:#69d2e7;margin-top:20px;cursor:default;width:auto}
|
||||
ul{list-style-type:none;padding:0 0 0 20px}
|
||||
.nav ul{line-height:14px;padding-left:0;margin:5px 0 0}
|
||||
.nav ul a,.nav ul a:visited,span{display:inline;color:#000;font-family:Verdana,Geneva,sans-serif;
|
||||
font-size:11px;font-weight:400;margin:0}
|
||||
.inset{margin-left:20px;font-size:.9em}
|
||||
.nav li{width:auto;margin:0 0 3px}
|
||||
.alias{font-style:italic;margin-left:20px}
|
||||
table{border-collapse:collapse;border-spacing:0;border:2px solid #a7dbd8;margin:1.75em 0;padding:0}
|
||||
td,th{text-align:left;margin:0;padding:2px 5px;border:1px dotted #a7dbd8}
|
||||
th{border-top:2px solid #a7dbd8;border-bottom:2px solid #a7dbd8;color:#f00}
|
||||
code,pre{font-family:Consolas, monaco, monospace;font-weight:400}
|
||||
pre{background:#f5f5f5;white-space:pre-wrap;word-wrap:break-word;border-left:5px solid #a7dbd8;
|
||||
padding:1px 0 1px 15px;margin:1.2em 0}
|
||||
code,.nav-title{color:#f00}
|
||||
.end{margin-bottom:25px}
|
||||
.centre{text-align:center}
|
||||
#modes,#configProps{color:#f00}
|
||||
.spacer{line-height:0px}
|
||||
#faq{margin:3em 0 0}
|
||||
li span{float:right;margin-right:10px;color:#c0c0c0}
|
||||
#js{font:inherit;color:#f00}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="nav">
|
||||
|
||||
<a class='nav-title' href="#">API</a>
|
||||
|
||||
<b>CONSTRUCTOR</b>
|
||||
<ul><li><a href="#decimal">Decimal</a></li></ul>
|
||||
|
||||
<a href="#methods">Methods</a>
|
||||
<ul>
|
||||
<li><a href="#Dclone" >clone</a></li>
|
||||
<li><a href="#Dconfig">config</a></li>
|
||||
</ul>
|
||||
|
||||
<a href="#constructor-properties">Properties</a>
|
||||
<ul>
|
||||
<li><a href="#precision">precision</a></li>
|
||||
<li><a href="#rounding" >rounding</a></li>
|
||||
<li><a href="#toExpNeg" >toExpNeg</a></li>
|
||||
<li><a href="#toExpPos" >toExpPos</a></li>
|
||||
<li><a href="#ln10" >LN10</a></li>
|
||||
<li class='spacer'> </li>
|
||||
<li><a href="#modes">ROUND_UP</a></li>
|
||||
<li><a href="#modes">ROUND_DOWN</a></li>
|
||||
<li><a href="#modes">ROUND_CEIL</a></li>
|
||||
<li><a href="#modes">ROUND_FLOOR</a></li>
|
||||
<li><a href="#modes">ROUND_HALF_UP</a></li>
|
||||
<li><a href="#modes">ROUND_HALF_DOWN</a></li>
|
||||
<li><a href="#modes">ROUND_HALF_EVEN</a></li>
|
||||
<li><a href="#modes">ROUND_HALF_CEIL</a></li>
|
||||
<li><a href="#modes">ROUND_HALF_FLOOR</a></li>
|
||||
<li><a href="#modes">EUCLID</a></li>
|
||||
</ul>
|
||||
|
||||
<b> INSTANCE </b>
|
||||
|
||||
<a href="#prototype-methods">Methods</a>
|
||||
<ul>
|
||||
<li><a href="#abs" >absoluteValue </a><span>abs</span> </li>
|
||||
<li><a href="#cmp" >comparedTo </a><span>cmp</span> </li>
|
||||
<li><a href="#dp" >decimalPlaces </a><span>dp</span> </li>
|
||||
<li><a href="#div" >dividedBy </a><span>div</span> </li>
|
||||
<li><a href="#idiv" >dividedToIntegerBy </a><span>idiv</span> </li>
|
||||
<li><a href="#eq" >equals </a><span>eq</span> </li>
|
||||
<li><a href="#exp" >exponent </a> </li>
|
||||
<li><a href="#gt" >greaterThan </a><span>gt</span> </li>
|
||||
<li><a href="#gte" >greaterThanOrEqualTo </a><span>gte</span> </li>
|
||||
<li><a href="#isint" >isInteger </a><span>isint</span></li>
|
||||
<li><a href="#isneg" >isNegative </a><span>isneg</span></li>
|
||||
<li><a href="#ispos" >isPositive </a><span>ispos</span></li>
|
||||
<li><a href="#isZero" >isZero </a> </li>
|
||||
<li><a href="#lt" >lessThan </a><span>lt</span> </li>
|
||||
<li><a href="#lte" >lessThanOrEqualTo </a><span>lte</span> </li>
|
||||
<li><a href="#log" >logarithm </a><span>log</span> </li>
|
||||
<li><a href="#sub" >minus </a><span>sub</span> </li>
|
||||
<li><a href="#mod" >modulo </a><span>mod</span> </li>
|
||||
<li><a href="#exp" >naturalExponential </a><span>exp</span> </li>
|
||||
<li><a href="#ln" >naturalLogarithm </a><span>ln</span> </li>
|
||||
<li><a href="#neg" >negated </a><span>neg</span> </li>
|
||||
<li><a href="#add" >plus </a><span>add</span> </li>
|
||||
<li><a href="#sd" >precision </a><span>sd</span> </li>
|
||||
<li><a href="#sqrt" >squareRoot </a><span>sqrt</span> </li>
|
||||
<li><a href="#mul" >times </a><span>mul</span> </li>
|
||||
<li><a href="#todp" >toDecimalPlaces </a><span>todp</span> </li>
|
||||
<li><a href="#toExponential">toExponential </a> </li>
|
||||
<li><a href="#toFixed" >toFixed </a> </li>
|
||||
<li><a href="#toInteger" >toInteger </a><span>toint</span></li>
|
||||
<li><a href="#toJSON" >toJSON </a> </li>
|
||||
<li><a href="#toNumber" >toNumber </a> </li>
|
||||
<li><a href="#pow" >toPower </a><span>pow</span> </li>
|
||||
<li><a href="#toPrecision" >toPrecision </a> </li>
|
||||
<li><a href="#tosd" >toSignificantDigits </a><span>tosd</span> </li>
|
||||
<li><a href="#toString" >toString </a> </li>
|
||||
<li><a href="#valueOf" >valueOf </a><span>val</span> </li>
|
||||
</ul>
|
||||
|
||||
<a href="#instance-properties">Properties</a>
|
||||
<ul>
|
||||
<li><a href="#digits" >d</a><span>digits</span></li>
|
||||
<li><a href="#exponent">e</a><span>exponent</span></li>
|
||||
<li><a href="#sign" >s</a><span>sign</span></li>
|
||||
</ul>
|
||||
|
||||
<a href="#Errors">Errors</a>
|
||||
<a class='end' href="#faq">FAQ</a>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<h1>decimal<span id='js'>.js</span>-light</h1>
|
||||
|
||||
<p>
|
||||
The light version of <a href='https://github.com/MikeMcl/decimal.js/'>decimal.js</a>, an
|
||||
arbitrary-precision Decimal type for JavaScript.
|
||||
</p>
|
||||
<p><a href='https://github.com/MikeMcl/decimal.js-light'>Hosted on GitHub</a>.</p>
|
||||
|
||||
<h2>API</h2>
|
||||
|
||||
<p>
|
||||
See the <a href='https://github.com/MikeMcl/decimal.js'>README</a> on GitHub for a quick-start
|
||||
introduction.
|
||||
</p>
|
||||
<p>
|
||||
In all examples below, <code>var</code> and semicolons are not shown, and if a commented-out
|
||||
value is in quotes it means <code>toString</code> has been called on the preceding expression.
|
||||
</p><br />
|
||||
<p>
|
||||
When the library is loaded, it defines a single function object,
|
||||
<a href='#decimal'><code>Decimal</code></a>, the constructor of Decimal instances.
|
||||
</p>
|
||||
<p>
|
||||
<i>
|
||||
If necessary, multiple Decimal constructors can be created, each with their own independent
|
||||
configuration, e.g. precision and range, which applies to all Decimal instances created from
|
||||
it.
|
||||
</i>
|
||||
</p>
|
||||
<p>
|
||||
<i>
|
||||
A new Decimal constructor is created by calling the <code><a href='#Dclone'>clone</a></code>
|
||||
method of an already existing Decimal constructor.
|
||||
</i>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h3 class='end'>CONSTRUCTOR</h3>
|
||||
|
||||
<h5 id="decimal">
|
||||
Decimal<code class='inset'>Decimal(value) <i>⇒ Decimal</i></code>
|
||||
</h5>
|
||||
<dl>
|
||||
<dt><code>value</code>: <i>number|string|Decimal</i></dt>
|
||||
<dd>
|
||||
Integer or float.
|
||||
</dd>
|
||||
<dd>
|
||||
The number of digits is not limited, except by JavaScript's maximum array size and, in
|
||||
practice, the processing time required.
|
||||
</dd>
|
||||
<dd>
|
||||
The maximum permissible exponent magnitude is approximately <code>9007199254740991</code>.
|
||||
</dd>
|
||||
<dd>
|
||||
String values may be in exponential (floating-point), as well as normal (fixed-point)
|
||||
notation.
|
||||
</dd>
|
||||
<dd>
|
||||
In exponential notation, <code>e</code> or <code>E</code> defines a power-of-ten exponent.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>Returns a new Decimal object instance.</p>
|
||||
<p>Throws on an invalid <code>value</code>.</p>
|
||||
<pre>
|
||||
x = new Decimal(9) // '9'
|
||||
y = new Decimal(x) // '9'
|
||||
|
||||
new Decimal('5032485723458348569331745.33434346346912144534543')
|
||||
new Decimal('4.321e+4') // '43210'
|
||||
new Decimal('-735.0918e-430') // '-7.350918e-428'
|
||||
new Decimal('5.6700000') // '5.67'
|
||||
new Decimal('.5') // '0.5'
|
||||
|
||||
new Decimal(0.046875) // '0.046875'
|
||||
new Decimal('0.046875000000') // '0.046875'
|
||||
|
||||
new Decimal(4.6875e-2) // '0.046875'
|
||||
new Decimal('468.75e-4') // '0.046875'</pre>
|
||||
|
||||
|
||||
|
||||
<h4 id="methods">Methods</h4>
|
||||
<p>The methods of a Decimal constructor.</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="Dclone">
|
||||
clone
|
||||
<code class='inset'>.clone([object]) <i>⇒ Decimal constructor</i></code>
|
||||
</h5>
|
||||
<p><code>object</code>: <i>object</i></p>
|
||||
<p>
|
||||
Returns a new independent Decimal constructor with configuration settings as described by
|
||||
<code>object</code> (see <a href='#Dconfig'><code>config</code></a>), or with the same
|
||||
settings as <code>this</code> Decimal constructor if <code>object</code> is omitted.
|
||||
</p>
|
||||
<pre>Decimal.config({ precision: 5 })
|
||||
D9 = Decimal.clone({ precision: 9 })
|
||||
|
||||
a = new Decimal(1)
|
||||
b = new D9(1)
|
||||
|
||||
a.div(3) // 0.33333
|
||||
b.div(3) // 0.333333333
|
||||
|
||||
// D9 = Decimal.clone({ precision: 9 }) is equivalent to:
|
||||
D9 = Decimal.clone()
|
||||
D9.config({ precision: 9 })</pre>
|
||||
<p>
|
||||
It is not inefficient in terms of memory usage to use multiple Decimal constructors as
|
||||
functions are shared between them.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="Dconfig">
|
||||
config<code class='inset'>.set(object) <i>⇒ Decimal constructor</i></code>
|
||||
</h5>
|
||||
<p><code>object</code>: <i>object</i></p>
|
||||
<p>
|
||||
Configures the 'global' settings for <code>this</code> particular Decimal constructor, i.e.
|
||||
the settings which apply to operations performed on the Decimal instances created by it.
|
||||
</p>
|
||||
<p>Returns <code>this</code> Decimal constructor.</p>
|
||||
<p>
|
||||
The configuration object, <code>object</code>, can contain some or all of the properties
|
||||
described in detail at <a href="#constructor-properties">Properties</a> and shown in the
|
||||
example below.
|
||||
</p>
|
||||
<p>
|
||||
The values of the configuration object properties are checked for validity and then stored as
|
||||
equivalently-named properties of <code>this</code> Decimal constructor.
|
||||
</p>
|
||||
<p>Throws on an invalid <code>object</code> or configuration property value.</p>
|
||||
<pre>
|
||||
// Defaults
|
||||
Decimal.config({
|
||||
precision: 20,
|
||||
rounding: 4,
|
||||
toExpNeg: -7,
|
||||
toExpPos: 21,
|
||||
LN10: new Decimal('2.30258509299404568401799145468436...')
|
||||
})
|
||||
|
||||
Decimal.set({ rounding: Decimal.ROUND_CEIL })
|
||||
</pre>
|
||||
<p>
|
||||
The properties of a Decimal constructor can also be set by direct assignment, but that will
|
||||
by-pass the validity checking that this method performs - which is not a problem if the user
|
||||
knows that the checks are unnecessary.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h4 id="constructor-properties">Properties</h4>
|
||||
<p>The properties of a Decimal constructor.</p>
|
||||
|
||||
|
||||
|
||||
<h6 id='configProps'>Configuration properties</h6>
|
||||
<p>
|
||||
The values of the configuration properties <a href='#precision'><code>precision</code></a>,
|
||||
<a href='#rounding'><code>rounding</code></a>, <a href='#toExpNeg'><code>toExpNeg</code></a>
|
||||
and <a href='#toExpPos'><code>toExpPos</code></a> are set using the
|
||||
<a href='#Dconfig'><code>config</code></a> method.
|
||||
</p>
|
||||
<p>
|
||||
As simple object properties they can be set directly without using
|
||||
<a href='#Dconfig'><code>config</code></a>, and it is fine to do so, but the values assigned
|
||||
will not then be checked for validity. For example:
|
||||
</p>
|
||||
<pre>Decimal.config({ precision: 0 })
|
||||
// '[DecimalError] Invalid argument: precision: 0'
|
||||
|
||||
Decimal.precision = 0
|
||||
// No error is thrown and the results of calculations are unreliable</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="precision">precision</h5>
|
||||
<p>
|
||||
<i>number</i>: integer, <code>1</code> to <code>1e+9</code> inclusive<br />
|
||||
Default value: <code>20</code>
|
||||
</p>
|
||||
<p>The <i>maximum</i> number of significant digits of the result of an operation.</p>
|
||||
<p>
|
||||
All functions which return a Decimal will return the value to <code>precision</code>
|
||||
significant digits except <a href='#decimal'><code>Decimal</code></a>,
|
||||
<a href='#abs'><code>absoluteValue</code></a>,
|
||||
<a href='#neg'><code>negated</code></a>, <a href='#round'><code>toInteger</code></a>, and
|
||||
<a href='#todp'><code>toDecimalPlaces</code></a>.
|
||||
</p>
|
||||
<pre>Decimal.config({ precision: 5 })
|
||||
Decimal.precision // 5</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="rounding">rounding</h5>
|
||||
<p>
|
||||
<i>number</i>: integer, <code>0</code> to <code>8</code> inclusive<br />
|
||||
Default value: <code>4</code> <a href="#modes">(<code>ROUND_HALF_UP</code>)</a>
|
||||
</p>
|
||||
<p>
|
||||
The default rounding mode used by <a href='#round'><code>toInteger</code></a>,
|
||||
<a href='#todp'><code>toDecimalPlaces</code></a>,
|
||||
<a href='#toExponential'><code>toExponential</code></a>,
|
||||
<a href='#toFixed'><code>toFixed</code></a>,
|
||||
<a href='#toPrecision'><code>toPrecision</code></a> and
|
||||
<a href='#tosd'><code>toSignificantDigits</code></a>.
|
||||
</p>
|
||||
<p>
|
||||
The <a href='#modes'>rounding modes</a> are available as enumerated properties of the
|
||||
constructor.
|
||||
</p>
|
||||
<pre>Decimal.config({ rounding: Decimal.ROUND_UP })
|
||||
Decimal.config({ rounding: 0 }) // equivalent
|
||||
Decimal.rounding // 0</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="toExpNeg">toExpNeg</h5>
|
||||
<p>
|
||||
<i>number</i>: integer, <code>-9e15</code> to <code>0</code> inclusive<br />
|
||||
Default value: <code>-7</code>
|
||||
</p>
|
||||
<p>
|
||||
The negative exponent value at and below which <a href='#toString'><code>toString</code></a>
|
||||
returns exponential notation.
|
||||
</p>
|
||||
<pre>Decimal.config({ toExpNeg: -7 })
|
||||
Decimal.toExpNeg // -7
|
||||
new Decimal(0.00000123) // '0.00000123' e is -6
|
||||
new Decimal(0.000000123) // '1.23e-7'
|
||||
|
||||
// Always return exponential notation:
|
||||
Decimal.config({ toExpNeg: 0 })</pre>
|
||||
<p>
|
||||
JavaScript numbers use exponential notation for negative exponents of <code>-7</code> and
|
||||
below.
|
||||
</p>
|
||||
<p>
|
||||
Regardless of the value of <code>toExpNeg</code>, the
|
||||
<a href='#toFixed'><code>toFixed</code></a> method will always return a value in normal
|
||||
notation and the <a href='#toExponential'><code>toExponential</code></a> method will always
|
||||
return a value in exponential form.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="toExpPos">toExpPos</h5>
|
||||
<p>
|
||||
<i>number</i>: integer, <code>0</code> to <code>9e15</code> inclusive<br />
|
||||
Default value: <code>20</code>
|
||||
</p>
|
||||
<p>
|
||||
The positive exponent value at and above which <a href='#toString'><code>toString</code></a>
|
||||
returns exponential notation.
|
||||
</p>
|
||||
<pre>Decimal.config({ toExpPos: 2 })
|
||||
Decimal.toExpPos // 2
|
||||
new Decimal(12.3) // '12.3' e is 1
|
||||
new Decimal(123) // '1.23e+2'
|
||||
|
||||
// Always return exponential notation:
|
||||
Decimal.config({ toExpPos: 0 })</pre>
|
||||
<p>
|
||||
JavaScript numbers use exponential notation for positive exponents of <code>20</code> and
|
||||
above.
|
||||
</p>
|
||||
<p>
|
||||
Regardless of the value of <code>toExpPos</code>, the
|
||||
<a href='#toFixed'><code>toFixed</code></a> method will always return a value in normal
|
||||
notation and the <a href='#toExponential'><code>toExponential</code></a> method will always
|
||||
return a value in exponential form.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="ln10">LN10</h5>
|
||||
<p>
|
||||
<i>string|Decimal</i>: the natural logarithm of <code>10</code><br />
|
||||
The default value has <code>115</code> digits
|
||||
</p>
|
||||
<p>
|
||||
The maximum precision of the <a href='#exp'><code>naturalExponential</code></a>,
|
||||
<a href='#ln'><code>naturalLogarithm</code></a>, <a href='#log'><code>logarithm</code></a>,
|
||||
and <a href='#pow'><code>toPower</code></a> methods is determined by the precision of the
|
||||
value of <code>LN10</code>.
|
||||
</p>
|
||||
<p>
|
||||
The default value of <code>LN10</code> enables a maximum precision of about <code>100</code>
|
||||
digits. To increase this, assign a new value to <code>LN10</code> using a string or Decimal
|
||||
value with about 15 digits more than the maximum precision required.
|
||||
</p>
|
||||
<p>
|
||||
An error will be thrown if the <code>LN10</code> value does not have sufficient precision to
|
||||
enable an operation to be performed.
|
||||
</p>
|
||||
<pre>
|
||||
Decimal.config({ LN10: '2.3025850929940456840179914546843642076011014886287729760333279009' })
|
||||
|
||||
Decimal.LN10.toFixed(5) // ''2.30259'</pre>
|
||||
|
||||
|
||||
|
||||
<h6 id="modes">Rounding modes</h6>
|
||||
<p>
|
||||
The library's enumerated rounding modes are stored as properties of the Decimal constructor.
|
||||
<br />They are not referenced internally by the library itself.
|
||||
</p>
|
||||
<p>Rounding modes 0 to 6 (inclusive) are the same as those of Java's BigDecimal class.</p>
|
||||
<table>
|
||||
<tr><th>Property</th><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><b>ROUND_UP</b></td><td class='centre'>0</td><td>Rounds away from zero</td></tr>
|
||||
<tr><td><b>ROUND_DOWN</b></td><td class='centre'>1</td><td>Rounds towards zero</td></tr>
|
||||
<tr><td><b>ROUND_CEIL</b></td><td class='centre'>2</td><td>Rounds towards Infinity</td></tr>
|
||||
<tr><td><b>ROUND_FLOOR</b></td><td class='centre'>3</td><td>Rounds towards -Infinity</td></tr>
|
||||
<tr>
|
||||
<td><b>ROUND_HALF_UP</b></td><td class='centre'>4</td>
|
||||
<td>Rounds towards nearest neighbour.<br />If equidistant, rounds away from zero</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>ROUND_HALF_DOWN</b></td><td class='centre'>5</td>
|
||||
<td>Rounds towards nearest neighbour.<br />If equidistant, rounds towards zero</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>ROUND_HALF_EVEN</b></td><td class='centre'>6</td>
|
||||
<td>
|
||||
Rounds towards nearest neighbour.<br />If equidistant, rounds towards even neighbour
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>ROUND_HALF_CEIL</b></td><td class='centre'>7</td>
|
||||
<td>Rounds towards nearest neighbour.<br />If equidistant, rounds towards Infinity</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>ROUND_HALF_FLOOR</b></td><td class='centre'>8</td>
|
||||
<td>Rounds towards nearest neighbour.<br />If equidistant, rounds towards -Infinity</td>
|
||||
</tr>
|
||||
</table>
|
||||
<pre>Decimal.config({ rounding: Decimal.ROUND_CEIL })
|
||||
Decimal.config({ rounding: 2 }) // equivalent
|
||||
Decimal.rounding // 2</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>INSTANCE</h3>
|
||||
|
||||
<h4 id="prototype-methods">Methods</h4>
|
||||
<p>The methods inherited by a Decimal instance from its constructor's prototype object.</p>
|
||||
<p>A Decimal instance is immutable in the sense that it is not changed by its methods.</p>
|
||||
<p>Methods that return a Decimal can be chained:</p>
|
||||
<pre>x = new Decimal(2).times('999.999999999999999').dividedBy(4).toFixed(2)</pre>
|
||||
<p>Methods do not round their arguments before execution.</p>
|
||||
<p>
|
||||
Many method names have a shorter alias. (Internally, the library always uses the shorter
|
||||
method names.)
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="abs">absoluteValue<code class='inset'>.abs() <i>⇒ Decimal</i></code></h5>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the absolute value, i.e. the magnitude, of the value of
|
||||
this Decimal.
|
||||
</p>
|
||||
<p>
|
||||
The return value is not affected by the value of the
|
||||
<a href='#precision'><code>precision</code></a> setting.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(-0.8)
|
||||
y = x.absoluteValue() // '0.8'
|
||||
z = y.abs() // '0.8'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="cmp">comparedTo<code class='inset'>.cmp(x) <i>⇒ number</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<table>
|
||||
<tr><th>Returns</th><th> </th></tr>
|
||||
<tr>
|
||||
<td class='centre'><code>1</code></td>
|
||||
<td>if the value of this Decimal is greater than the value of <code>x</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='centre'><code>-1</code></td>
|
||||
<td>if the value of this Decimal is less than the value of <code>x</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='centre'><code>0</code></td>
|
||||
<td>if this Decimal and <code>x</code> have the same value</td>
|
||||
</tr>
|
||||
</table>
|
||||
<pre>
|
||||
x = new Decimal(4)
|
||||
y = new Decimal(5)
|
||||
x.comparedTo(y) // -1
|
||||
x.comparedTo(x.plus(1)) // 0</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="dp">decimalPlaces<code class='inset'>.dp() <i>⇒ number</i></code></h5>
|
||||
<p>
|
||||
Returns the number of decimal places, i.e. the number of digits after the decimal point, of
|
||||
the value of this Decimal.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(1.234)
|
||||
x.decimalPlaces() // '3'
|
||||
y = new Decimal(987.654321)
|
||||
y.dp() // '6'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="div">dividedBy<code class='inset'>.div(x) <i>⇒ Decimal</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal divided by <code>x</code>,
|
||||
truncated to <a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(355)
|
||||
y = new Decimal(113)
|
||||
x.dividedBy(y) // '3.14159292035398230088'
|
||||
x.div(5) // '71'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="idiv">
|
||||
dividedToIntegerBy<code class='inset'>.idiv(x) <i>⇒ Decimal</i></code>
|
||||
</h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Return a new Decimal whose value is the integer part of dividing this Decimal by
|
||||
<code>x</code>, truncated to <code><a href='#precision'>precision</a></code> significant
|
||||
digits.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(5)
|
||||
y = new Decimal(3)
|
||||
x.dividedToIntegerBy(y) // '1'
|
||||
x.idiv(0.7) // '7'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="eq">equals<code class='inset'>.eq(x) <i>⇒ boolean</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns <code>true</code> if the value of this Decimal equals the value of <code>x</code>,
|
||||
otherwise returns <code>false</code>.
|
||||
</p>
|
||||
<p>Note: This method uses the <code>cmp</code> method internally.</p>
|
||||
<pre>
|
||||
0 === 1e-324 // true
|
||||
x = new Decimal(0)
|
||||
x.equals('1e-324') // false</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="exp">exponent<code class='inset'>.exponent() <i>⇒ number</i></code></h5>
|
||||
<p>Returns the exponent value of this Decimal.</p>
|
||||
<pre>
|
||||
x = new Decimal(1234.567)
|
||||
x.exponent() // 3</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="gt">greaterThan<code class='inset'>.gt(x) <i>⇒ boolean</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns <code>true</code> if the value of this Decimal is greater than the value of
|
||||
<code>x</code>, otherwise returns <code>false</code>.
|
||||
</p>
|
||||
<p>Note: This method uses the <code>cmp</code> method internally.</p>
|
||||
<pre>
|
||||
0.1 > (0.3 - 0.2) // true
|
||||
x = new Decimal(0.1)
|
||||
x.greaterThan(Decimal(0.3).minus(0.2)) // false
|
||||
new Decimal(0).gt(x) // false</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="gte">
|
||||
greaterThanOrEqualTo<code class='inset'>.gte(x) <i>⇒ boolean</i></code>
|
||||
</h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns <code>true</code> if the value of this Decimal is greater than or equal to the value
|
||||
of <code>x</code>, otherwise returns <code>false</code>.
|
||||
</p>
|
||||
<p>Note: This method uses the <code>cmp</code> method internally.</p>
|
||||
<pre>
|
||||
(0.3 - 0.2) >= 0.1 // false
|
||||
x = new Decimal(0.3).minus(0.2)
|
||||
x.greaterThanOrEqualTo(0.1) // true
|
||||
new Decimal(1).gte(x) // true</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="isint">isInteger<code class='inset'>.isint() <i>⇒ boolean</i></code></h5>
|
||||
<p>
|
||||
Returns <code>true</code> if the value of this Decimal is a whole number, otherwise returns
|
||||
<code>false</code>.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(1)
|
||||
x.isInteger() // true
|
||||
y = new Decimal(123.456)
|
||||
y.isint() // false</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="isneg">isNegative<code class='inset'>.isneg() <i>⇒ boolean</i></code></h5>
|
||||
<p>
|
||||
Returns <code>true</code> if the value of this Decimal is negative, otherwise returns
|
||||
<code>false</code>.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(0)
|
||||
x.isNegative() // false
|
||||
y = new Decimal(2)
|
||||
y.isneg // false</pre>
|
||||
<p>Note: <code>n < 0</code> can be used if <code>n <= -Number.MIN_VALUE</code>.</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="ispos">isPositive<code class='inset'>.ispos() <i>⇒ boolean</i></code></h5>
|
||||
<p>
|
||||
Returns <code>true</code> if the value of this Decimal is positive, otherwise returns
|
||||
<code>false</code>.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(0)
|
||||
x.isPositive() // false
|
||||
y = new Decimal(-2)
|
||||
y.ispos // false</pre>
|
||||
<p>Note: <code>n < 0</code> can be used if <code>n <= -Number.MIN_VALUE</code>.</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="isZero">isZero<code class='inset'>.isZero() <i>⇒ boolean</i></code></h5>
|
||||
<p>
|
||||
Returns <code>true</code> if the value of this Decimal is zero or minus zero, otherwise
|
||||
returns <code>false</code>.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(0)
|
||||
x.isZero() // true</pre>
|
||||
<p>Note: <code>n == 0</code> can be used if <code>n >= Number.MIN_VALUE</code>.</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="lt">lessThan<code class='inset'>.lt(x) <i>⇒ boolean</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns <code>true</code> if the value of this Decimal is less than the value of
|
||||
<code>x</code>, otherwise returns <code>false</code>.
|
||||
</p>
|
||||
<p>Note: This method uses the <code>cmp</code> method internally.</p>
|
||||
<pre>
|
||||
(0.3 - 0.2) < 0.1 // true
|
||||
x = new Decimal(0.3).minus(0.2)
|
||||
x.lessThan(0.1) // false
|
||||
new Decimal(0).lt(x) // true</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="lte">lessThanOrEqualTo<code class='inset'>.lte(x) <i>⇒ boolean</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns <code>true</code> if the value of this Decimal is less than or equal to the value of
|
||||
<code>x</code>, otherwise returns <code>false</code>.
|
||||
</p>
|
||||
<p>Note: This method uses the <code>cmp</code> method internally.</p>
|
||||
<pre>
|
||||
0.1 <= (0.3 - 0.2) // false
|
||||
x = new Decimal(0.1)
|
||||
x.lessThanOrEqualTo(Decimal(0.3).minus(0.2)) // true
|
||||
new Decimal(-1).lte(x) // true</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="log">logarithm<code class='inset'>.log(x) <i>⇒ Decimal</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the base <code>x</code> logarithm of the value of this
|
||||
Decimal, truncated to <a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<p>
|
||||
If <code>x</code> is omitted, the base 10 logarithm of the value of this Decimal will be
|
||||
returned.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(1000)
|
||||
x.logarithm() // '3'
|
||||
y = new Decimal(256)
|
||||
y.log(2) // '8'</pre>
|
||||
<p>The maximum error will be <code>1</code> <i>ulp</i> (unit in the last place).</p>
|
||||
<p>Logarithms to base <code>2</code> or <code>10</code> will always be correct.</p>
|
||||
<p>The performance of this method degrades exponentially with increasing digits.</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="sub">minus<code class='inset'>.minus(x) <i>⇒ Decimal</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal minus <code>x</code>, truncated
|
||||
to <a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<pre>
|
||||
0.3 - 0.1 // 0.19999999999999998
|
||||
x = new Decimal(0.3)
|
||||
x.minus(0.1) // '0.2'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="mod">modulo<code class='inset'>.mod(x) <i>⇒ Decimal</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal modulo <code>x</code>,
|
||||
truncated to <a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<pre>
|
||||
1 % 0.9 // 0.09999999999999998
|
||||
x = new Decimal(1)
|
||||
y = x.modulo(0.9) // '0.1'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="exp">naturalExponential<code class='inset'>.exp() <i>⇒ Decimal</i></code></h5>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the base <code>e</code> (Euler's number, the base of the
|
||||
natural logarithm) exponential of the value of this Decimal, truncated to
|
||||
<a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<p>
|
||||
The <code><a href='#ln'>naturalLogarithm</a></code> function is the inverse of this function.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(1)
|
||||
x.naturalExponential() // '2.7182818284590452354'
|
||||
y = new Decimal(2)
|
||||
y.exp() // '7.3890560989306502272'</pre>
|
||||
<p>The maximum error will be <code>1</code> <i>ulp</i> (unit in the last place).</p>
|
||||
<p>The performance of this method degrades exponentially with increasing digits.</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="ln">naturalLogarithm<code class='inset'>.ln() <i>⇒ Decimal</i></code></h5>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the natural logarithm of the value of this Decimal,
|
||||
truncated to <a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<p>
|
||||
The natural logarithm is the inverse of the <code><a href='#exp'>naturalExponential</a></code>
|
||||
function.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(10)
|
||||
x.naturalLogarithm() // '2.3026'
|
||||
y = new Decimal('1.23e+30')
|
||||
y.ln() // '69.28'</pre>
|
||||
<p>
|
||||
The mathematical result of the natural logarithm function is non-terminating, unless its
|
||||
argument is <code>1</code>.
|
||||
</p>
|
||||
<p>
|
||||
The time-taken by this method increases exponentially with increasing digits.
|
||||
</p>
|
||||
<p>
|
||||
See <a href='#ln10'>LN10</a> to configure the maximum precision available.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="neg">negated<code class='inset'>.neg() <i>⇒ Decimal</i></code></h5>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal negated, i.e. multiplied by
|
||||
<code>-1</code>.
|
||||
</p>
|
||||
<p>
|
||||
The return value is not affected by the value of the
|
||||
<a href='#precision'><code>precision</code></a> setting.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(1.8)
|
||||
x.negated() // '-1.8'
|
||||
y = new Decimal(-1.3)
|
||||
y.neg() // '1.3'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="add">plus<code class='inset'>.plus(x) <i>⇒ Decimal</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal plus <code>x</code>, truncated
|
||||
to <a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<pre>
|
||||
0.1 + 0.2 // 0.30000000000000004
|
||||
x = new Decimal(0.1)
|
||||
y = x.plus(0.2) // '0.3'
|
||||
new Decimal(0.7).plus(x).plus(y) // '1.1'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="sd">precision<code class='inset'>.sd([include_zeros]) <i>⇒ number</i></code></h5>
|
||||
<p>Returns the number of significant digits of the value of this Decimal.</p>
|
||||
<p>
|
||||
If <code>include_zeros</code> is <code>true</code> or <code>1</code> then any trailing zeros
|
||||
of the integer part of a number are counted as significant digits, otherwise they are not.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(1.234)
|
||||
x.precision() // '4'
|
||||
y = new Decimal(987000)
|
||||
y.sd() // '3'
|
||||
y.sd(true) // '6'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="sqrt">squareRoot<code class='inset'>.sqrt() <i>⇒ Decimal</i></code></h5>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the square root of this Decimal, truncated to
|
||||
<a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<p>
|
||||
This method is much faster than using the <a href='#pow'><code>toPower</code></a> method with
|
||||
an exponent of <code>0.5</code>.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(16)
|
||||
x.squareRoot() // '4'
|
||||
y = new Decimal(3)
|
||||
y.sqrt() // '1.73205080756887729353'
|
||||
y.sqrt().eq( y.pow(0.5) ) // true</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="mul">times<code class='inset'>.times(x) <i>⇒ Decimal</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i></p>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal times <code>x</code>,
|
||||
truncated to <a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<pre>
|
||||
0.6 * 3 // 1.7999999999999998
|
||||
x = new Decimal(0.6)
|
||||
y = x.times(3) // '1.8'
|
||||
new Decimal('7e+500').times(y) // '1.26e+501'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="todp">
|
||||
toDecimalPlaces<code class='inset'>.todp([dp [, rm]]) <i>⇒ Decimal</i></code>
|
||||
</h5>
|
||||
<p>
|
||||
<code>dp</code>: <i>number</i>: integer, <code>0</code> to <code>1e+9</code> inclusive<br />
|
||||
<code>rm</code>: <i>number</i>: integer, <code>0</code> to <code>8</code> inclusive.
|
||||
</p>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal rounded to a maximum of
|
||||
<code>dp</code> decimal places using rounding mode <code>rm</code>.
|
||||
</p>
|
||||
<p>
|
||||
If <code>dp</code> is omitted, the return value will have the same value as this Decimal.
|
||||
</p>
|
||||
<p>
|
||||
If <code>rm</code> is omitted, rounding mode <a href='#rounding'><code>rounding</code></a>
|
||||
is used.
|
||||
</p>
|
||||
<p>Throws on an invalid <code>dp</code> or <code>rm</code> value.</p>
|
||||
<pre>
|
||||
x = new Decimal(12.24567)
|
||||
x.toDecimalPlaces(0) // '12'
|
||||
x.toDecimalPlaces(1, 0) // '12.3'
|
||||
|
||||
y = new Decimal(9876.54321)
|
||||
y.todp(3) // '9876.543'
|
||||
y.todp(1, 0) // '9876.6'
|
||||
y.todp(1, Decimal.ROUND_DOWN) // '9876.5'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="toExponential">
|
||||
toExponential<code class='inset'>.toExponential([dp [, rm]]) <i>⇒ string</i></code>
|
||||
</h5>
|
||||
<p>
|
||||
<code>dp</code>: <i>number</i>: integer, <code>0</code> to <code>1e+9</code> inclusive<br />
|
||||
<code>rm</code>: <i>number</i>: integer, <code>0</code> to <code>8</code> inclusive
|
||||
</p>
|
||||
<p>
|
||||
Returns a string representing the value of this Decimal in exponential notation rounded
|
||||
using rounding mode <code>rm</code> to <code>dp</code> decimal places, i.e with one digit
|
||||
before the decimal point and <code>dp</code> digits after it.
|
||||
</p>
|
||||
<p>
|
||||
If the value of this Decimal in exponential notation has fewer than <code>dp</code> fraction
|
||||
digits, the return value will be appended with zeros accordingly.
|
||||
</p>
|
||||
<p>
|
||||
If <code>dp</code> is omitted, the number of digits after the decimal point defaults to the
|
||||
minimum number of digits necessary to represent the value exactly.
|
||||
</p>
|
||||
<p>
|
||||
If <code>rm</code> is omitted, rounding mode <a href='#rounding'><code>rounding</code></a> is
|
||||
used.
|
||||
</p>
|
||||
<p>Throws on an invalid <code>dp</code> or <code>rm</code> value.</p>
|
||||
<pre>
|
||||
x = 45.6
|
||||
b = new Decimal(x)
|
||||
x.toExponential() // '4.56e+1'
|
||||
y.toExponential() // '4.56e+1'
|
||||
x.toExponential(0) // '5e+1'
|
||||
y.toExponential(0) // '5e+1'
|
||||
x.toExponential(1) // '4.6e+1'
|
||||
y.toExponential(1) // '4.6e+1'
|
||||
y.toExponential(1, 1) // '4.5e+1' (ROUND_DOWN)
|
||||
x.toExponential(3) // '4.560e+1'
|
||||
y.toExponential(3) // '4.560e+1'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="toFixed">
|
||||
toFixed<code class='inset'>.toFixed([dp [, rm]]) <i>⇒ string</i></code>
|
||||
</h5>
|
||||
<p>
|
||||
<code>dp</code>: <i>number</i>: integer, <code>0</code> to <code>1e+9</code> inclusive<br />
|
||||
<code>rm</code>: <i>number</i>: integer, <code>0</code> to <code>8</code> inclusive
|
||||
</p>
|
||||
<p>
|
||||
Returns a string representing the value of this Decimal in normal (fixed-point) notation
|
||||
rounded to <code>dp</code> decimal places using rounding mode <code>rm</code>.
|
||||
</p>
|
||||
<p>
|
||||
If the value of this Decimal in normal notation has fewer than <code>dp</code> fraction
|
||||
digits, the return value will be appended with zeros accordingly.
|
||||
</p>
|
||||
<p>
|
||||
Unlike <code>Number.prototype.toFixed</code>, which returns exponential notation if a number
|
||||
is greater or equal to <code>10<sup>21</sup></code>, this method will always return normal
|
||||
notation.
|
||||
</p>
|
||||
<p>
|
||||
If <code>dp</code> is omitted, the return value will be unrounded and in normal notation. This
|
||||
is unlike <code>Number.prototype.toFixed</code>, which returns the value to zero decimal
|
||||
places, but is useful when because of the current
|
||||
<a href="#toExpNeg"><code>toExpNeg</code></a> or
|
||||
<a href="#toExpPos"><code>toExpNeg</code></a> values,
|
||||
<code><a href='#toString'>toString</a></code> returns exponential notation.
|
||||
</p>
|
||||
<p>
|
||||
If <code>rm</code> is omitted, rounding mode <a href='#rounding'><code>rounding</code></a> is
|
||||
used.
|
||||
</p>
|
||||
<p>Throws on an invalid <code>dp</code> or <code>rm</code> value.</p>
|
||||
<pre>
|
||||
x = 3.456
|
||||
b = new Decimal(x)
|
||||
x.toFixed() // '3'
|
||||
y.toFixed() // '3.456'
|
||||
y.toFixed(0) // '3'
|
||||
x.toFixed(2) // '3.46'
|
||||
y.toFixed(2) // '3.46'
|
||||
y.toFixed(2, 1) // '3.45' (ROUND_DOWN)
|
||||
x.toFixed(5) // '3.45600'
|
||||
y.toFixed(5) // '3.45600'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="toInteger">toInteger<code class='inset'>.toint() <i>⇒ Decimal</i></code></h5>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal rounded to a whole number using
|
||||
rounding mode <a href='#rounding'><code>rounding</code></a>.
|
||||
</p>
|
||||
<p>
|
||||
To emulate <code>Math.round</code>, set <a href='#rounding'><code>rounding</code></a> to
|
||||
<code>7</code>, i.e. <a href='#modes'><code>ROUND_HALF_CEIL</code></a>.
|
||||
</p>
|
||||
<pre>
|
||||
Decimal.config({ rounding: 4 })
|
||||
x = 1234.5
|
||||
x.toInteger() // '1235'
|
||||
|
||||
Decimal.rounding = Decimal.ROUND_DOWN
|
||||
x.toint() // '1234'
|
||||
x // '1234.5'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="toJSON">toJSON<code class='inset'>.toJSON() <i>⇒ string</i></code></h5>
|
||||
<p>As <a href='#toString'><code>toString</code></a>.</p>
|
||||
|
||||
|
||||
|
||||
<h5 id="toNumber">toNumber<code class='inset'>.toNumber() <i>⇒ number</i></code></h5>
|
||||
<p>Returns the value of this Decimal converted to a primitive number.</p>
|
||||
<p>
|
||||
Type coercion with, for example, JavaScript's unary plus operator will also work, except that
|
||||
a Decimal with the value minus zero will convert to positive zero.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(456.789)
|
||||
x.toNumber() // 456.789
|
||||
+x // 456.789
|
||||
|
||||
y = new Decimal('45987349857634085409857349856430985')
|
||||
y.toNumber() // 4.598734985763409e+34</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="pow">toPower<code class='inset'>.pow(x) <i>⇒ Decimal</i></code></h5>
|
||||
<p><code>x</code>: <i>number|string|Decimal</i>: integer or non-integer</p>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal raised to the power
|
||||
<code>x</code>, truncated to <a href='#precision'><code>precision</code></a> significant
|
||||
digits.
|
||||
</p>
|
||||
<p>
|
||||
The performance of this method degrades exponentially with increasing digits.<br />
|
||||
For non-integer exponents in particular, the performance of this method may not be adequate.
|
||||
</p>
|
||||
<p>The maximum error will be <code>1</code> <i>ulp</i> (unit in the last place). </p>
|
||||
<pre>
|
||||
Math.pow(0.7, 2) // 0.48999999999999994
|
||||
x = new Decimal(0.7)
|
||||
x.toPower(2) // '0.49'
|
||||
new Decimal(3).pow(-2) // '0.11111111111111111111'
|
||||
|
||||
new Decimal(1217652.23).pow('98765.489305603941')
|
||||
// '4.8227010515242461181e+601039'</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
<h5 id="toPrecision">
|
||||
toPrecision<code class='inset'>.toPrecision([sd [, rm]]) <i>⇒ string</i></code>
|
||||
</h5>
|
||||
<p>
|
||||
<code>sd</code>: <i>number</i>: integer, <code>1</code> to <code>1e+9</code> inclusive<br />
|
||||
<code>rm</code>: <i>number</i>: integer, <code>0</code> to <code>8</code> inclusive
|
||||
</p>
|
||||
<p>
|
||||
Returns a string representing the value of this Decimal rounded to <code>sd</code> significant
|
||||
digits using rounding mode <code>rm</code>.
|
||||
</p>
|
||||
<p>
|
||||
If <code>sd</code> is less than the number of digits necessary to represent the integer part
|
||||
of the value in normal (fixed-point) notation, then exponential notation is used.
|
||||
</p>
|
||||
<p>
|
||||
If <code>sd</code> is omitted, the return value is the same as
|
||||
<code><a href='#toString'>toString</a></code>.
|
||||
</p>
|
||||
<p>
|
||||
If <code>rm</code> is omitted, rounding mode <a href='#rounding'><code>rounding</code></a> is
|
||||
used.
|
||||
</p>
|
||||
<p>Throws on an invalid <code>sd</code> or <code>rm</code> value.</p>
|
||||
<pre>
|
||||
x = 45.6
|
||||
b = new Decimal(x)
|
||||
x.toPrecision() // '45.6'
|
||||
y.toPrecision() // '45.6'
|
||||
x.toPrecision(1) // '5e+1'
|
||||
y.toPrecision(1) // '5e+1'
|
||||
y.toPrecision(2, 0) // '4.6e+1' (ROUND_UP)
|
||||
y.toPrecision(2, 1) // '4.5e+1' (ROUND_DOWN)
|
||||
x.toPrecision(5) // '45.600'
|
||||
y.toPrecision(5) // '45.600'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="tosd">
|
||||
toSignificantDigits<code class='inset'>.tosd([sd [, rm]]) <i>⇒ Decimal</i></code>
|
||||
</h5>
|
||||
<p>
|
||||
<code>sd</code>: <i>number</i>: integer, <code>1</code> to <code>1e+9</code> inclusive.<br />
|
||||
<code>rm</code>: <i>number</i>: integer, <code>0</code> to <code>8</code> inclusive.
|
||||
</p>
|
||||
<p>
|
||||
Returns a new Decimal whose value is the value of this Decimal rounded to a maximum of
|
||||
<code>sd</code> significant digits using rounding mode <code>rm</code>.
|
||||
</p>
|
||||
<p>
|
||||
If <code>sd</code> is omitted, the return value will be rounded to
|
||||
<a href='#precision'><code>precision</code></a> significant digits.
|
||||
</p>
|
||||
<p>
|
||||
If <code>rm</code> is omitted, rounding mode <a href='#rounding'><code>rounding</code></a>
|
||||
will be used.
|
||||
</p>
|
||||
<p>Throws on an invalid <code>sd</code> or <code>rm</code> value.</p>
|
||||
<pre>
|
||||
Decimal.config({ precision: 5, rounding: 4 })
|
||||
x = new Decimal(9876.54321)
|
||||
|
||||
x.toSignificantDigits() // '9876.5'
|
||||
x.toSignificantDigits(6) // '9876.54'
|
||||
x.toSignificantDigits(6, Decimal.ROUND_UP) // '9876.55'
|
||||
x.tosd(2) // '9900'
|
||||
x.tosd(2, 1) // '9800'
|
||||
x // '9876.54321'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="toString">toString<code class='inset'>.toString() <i>⇒ string</i></code></h5>
|
||||
<p>Returns a string representing the value of this Decimal.</p>
|
||||
<p>
|
||||
If this Decimal has a positive exponent that is equal to or greater than
|
||||
<a href="#toExpPos"><code>toExpPos</code></a>, or a negative exponent equal to or less than
|
||||
<a href="#toExpPos"><code>toExpNeg</code></a>, then exponential notation will be returned.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(750000)
|
||||
x.toString() // '750000'
|
||||
Decimal.config({ toExpPos: 5 })
|
||||
x.toString() // '7.5e+5'
|
||||
|
||||
Decimal.config({ precision: 4 });
|
||||
y = new Decimal('1.23456789')
|
||||
y.toString() // '1.23456789'</pre>
|
||||
|
||||
|
||||
|
||||
<h5 id="valueOf">valueOf<code class='inset'>.val() <i>⇒ string</i></code></h5>
|
||||
<p>As <a href='#toString'><code>toString</code></a>.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 id="instance-properties">Properties</h4>
|
||||
<p>
|
||||
The value of a Decimal is stored in a normalised base <code>10000000</code> floating point
|
||||
format.
|
||||
</p>
|
||||
<p>
|
||||
A Decimal instance is an object with three properties:
|
||||
</p>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
<th>Description</th>
|
||||
<th>Type</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='centre' id='digits'><b>d</b></td>
|
||||
<td>digits</td>
|
||||
<td><i>number</i><code style='color:#000'>[]</code></td>
|
||||
<td> Array of integers, each <code>0</code> - <code>1e7</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='centre' id='exponent'><b>e</b></td>
|
||||
<td>exponent*</td>
|
||||
<td><i>number</i></td>
|
||||
<td>Integer, <code>-1286742750677284</code> to <code>1286742750677284</code> inclusive</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='centre' id='sign'><b>s</b></td>
|
||||
<td>sign</td>
|
||||
<td><i>number</i></td>
|
||||
<td><code>-1</code>, <code>0</code>, or <code>1</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
*This is the exponent in base <code>10000000</code>. To get the base 10 exponent, use the
|
||||
<a href='#exp'><code>exponent</code></a> method.
|
||||
</p>
|
||||
<p>The properties are best considered to be read-only.</p>
|
||||
<p>
|
||||
As with JavaScript numbers, the original exponent and fractional trailing zeros of a number
|
||||
are not preserved.
|
||||
</p>
|
||||
<pre>
|
||||
x = new Decimal(0.123) // '0.123'
|
||||
x.toExponential() // '1.23e-1'
|
||||
x.d // [ 1230000 ]
|
||||
x.e // -1
|
||||
x.s // 1
|
||||
|
||||
y = new Number(-123.4567000e+2) // '-12345.67'
|
||||
y.toExponential() // '-1.234567e+4'
|
||||
z = new Decimal('-123.4567000e+2') // '-12345.67'
|
||||
z.toExponential() // '-1.234567e+4'
|
||||
z.d // [ 12345, 6700000 ]
|
||||
z.e // 4
|
||||
z.s // -1</pre>
|
||||
|
||||
|
||||
|
||||
<h4 id='Errors'>Errors</h4>
|
||||
<p>
|
||||
The errors that are thrown are generic <code>Error</code> objects whose <code>message</code>
|
||||
property begins with <code>"[DecimalError]"</code>.
|
||||
</p>
|
||||
<p>To determine if an exception is a Decimal Error:</p>
|
||||
<pre>
|
||||
try {
|
||||
// ...
|
||||
} catch (e) {
|
||||
if ( e instanceof Error && /DecimalError/.test(e.message) ) {
|
||||
// ...
|
||||
}
|
||||
}</pre>
|
||||
|
||||
|
||||
|
||||
<h2 id='faq'>FAQ</h2>
|
||||
<h6>Why are trailing fractional zeros removed from Decimals?</h6>
|
||||
<p>
|
||||
Some arbitrary-precision libraries retain trailing fractional zeros as they can indicate the
|
||||
precision of a value. This can be useful but the results of arithmetic operations can be
|
||||
misleading.
|
||||
</p>
|
||||
<pre>
|
||||
x = new BigDecimal("1.0")
|
||||
y = new BigDecimal("1.1000")
|
||||
z = x.add(y) // 2.1000
|
||||
|
||||
x = new BigDecimal("1.20")
|
||||
y = new BigDecimal("3.45000")
|
||||
z = x.multiply(y) // 4.1400000</pre>
|
||||
<p>
|
||||
To specify the precision of a value is to specify that the value lies
|
||||
within a certain range.
|
||||
</p>
|
||||
<p>
|
||||
In the first example, <code>x</code> has a value of <code>1.0</code>. The trailing zero shows
|
||||
the precision of the value, implying that it is in the range <code>0.95</code> to
|
||||
<code>1.05</code>. Similarly, the precision indicated by the trailing zeros of <code>y</code>
|
||||
indicates that the value is in the range <code>1.09995</code> to <code>1.10005</code>.
|
||||
</p>
|
||||
<p>
|
||||
If we add the two lowest values in the ranges we have, <code>0.95 + 1.09995 = 2.04995</code>,
|
||||
and if we add the two highest values we have, <code>1.05 + 1.10005 = 2.15005</code>, so the
|
||||
range of the result of the addition implied by the precision of its operands is
|
||||
<code>2.04995</code> to <code>2.15005</code>.
|
||||
</p>
|
||||
<p>
|
||||
The result given by BigDecimal of <code>2.1000</code> however, indicates that the value is in
|
||||
the range <code>2.09995</code> to <code>2.10005</code> and therefore the precision implied by
|
||||
its trailing zeros may be misleading.
|
||||
</p>
|
||||
<p>
|
||||
In the second example, the true range is <code>4.122744</code> to <code>4.157256</code> yet
|
||||
the BigDecimal answer of <code>4.1400000</code> indicates a range of <code>4.13999995</code>
|
||||
to <code>4.14000005</code>. Again, the precision implied by the trailing zeros may be
|
||||
misleading.
|
||||
</p>
|
||||
<p>
|
||||
This library, like binary floating point and most calculators, does not retain trailing
|
||||
fractional zeros. Instead, the <code>toExponential</code>, <code>toFixed</code> and
|
||||
<code>toPrecision</code> methods enable trailing zeros to be added if and when required.<br />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+1
File diff suppressed because one or more lines are too long
+36
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "decimal.js-light",
|
||||
"description": "An arbitrary-precision Decimal type for JavaScript.",
|
||||
"version": "2.5.1",
|
||||
"keywords": [
|
||||
"arbitrary",
|
||||
"precision",
|
||||
"arithmetic",
|
||||
"big",
|
||||
"number",
|
||||
"decimal",
|
||||
"float",
|
||||
"biginteger",
|
||||
"bigdecimal",
|
||||
"bignumber",
|
||||
"bigint",
|
||||
"bignum"
|
||||
],
|
||||
"repository" : {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MikeMcl/decimal.js-light.git"
|
||||
},
|
||||
"main": "decimal",
|
||||
"module": "decimal.mjs",
|
||||
"browser": "decimal.js",
|
||||
"types": "decimal.d.ts",
|
||||
"author": {
|
||||
"name": "Michael Mclaughlin",
|
||||
"email": "M8ch88l@gmail.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "node ./test/test.js",
|
||||
"build": "uglifyjs decimal.js --source-map doc/decimal.js.map -c -m -o decimal.min.js --preamble \"/* decimal.js-light v2.5.1 https://github.com/MikeMcl/decimal.js-light/LICENCE */\""
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user