jsbd
Version:
[](https://www.npmjs.com/package/jsbd)
346 lines (257 loc) • 12.5 kB
Markdown
# JSBD
[](https://www.npmjs.com/package/jsbd)
## a JSBI style polyfill for BigDecimal
This is a polyfill for BigDecimal , which implement tc39-bigDecimal proposal https://github.com/tc39/proposal-decimal
And some result of the method referred Java.math.BigDecimal
typescript and 100% case coverage
## install
```
// use npm
npm install jsbd
// or use yarn
yarn add jsbd
```
## usage
### JSBD.BigDecimal
use `JSBD.BigDecimal` to init a BigDecimal object
```js
import JSBD from 'jsbd'
let a = JSBD.BigDecimal(3) // returns 3m
let b = JSBD.BigDecimal('345') // returns 345m
let c = JSBD.BigDecimal('115e-10') // returns 0.0000000115m
let d = JSBD.BigDecimal(2545562323242232323n) // results 2545562323242232323m
let e = JSBD.BigDecimal(true) // Throws TypeError
let f = JSBD.BigDecimal(false) // Throws TypeError
let g = JSBD.BigDecimal(null) // Throws TypeError
let h = JSBD.BigDecimal(undefined) // Throws TypeError
let i = JSBD.BigDecimal(0.1) // returns 0.1m
```
### JSBD.round(value [, options])
This is the function to be used when there's need to round `BigDecimals` in some specific way. It rounds the
`BigDecimal` passed as parameter, taking in consideration `options`.
- `value`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `options`: It is an object indicating how the round operation should be performed. It is an object that can
contain roundingMode and maximumFractionDigits properties.
- `maximumFractionDigits`: This options indicates the maximum of factional digits the rounding operation
should preserve. If it is `undefined`, round operations returns `value`.
- `roundingMode`: This option indicates which algorithm is used to round the given `BigDecimal`. Each
possible option is described below.
- down: round towards zero.
- half down: round towards "nearest neighbor". If both neighbors are equidistant, it rounds down.
- half up: round towards "nearest neighbor". If both neighbors are equidistant, it rounds up.
- half even: round towards the "nearest neighbor". If both neighbors are equidistant, it rounds towards
the even neighbor.
- up: round away from zero.
```js
let a = JSBD.round(0.53m, { roundingMode: 'half up', maximumFractionDigits: 1 })
assert(a, 0.5m)
a = JSBD.round(0.53m, { roundingMode: 'half down', maximumFractionDigits: 1 })
assert(a, 0.5m)
a = JSBD.round(0.53m, { roundingMode: 'half even', maximumFractionDigits: 1 })
assert(a, 0.5m)
a = JSBD.round(0.31m, { roundingMode: 'down', maximumFractionDigits: 1 })
assert(a, 0.3m)
a = JSBD.round(0.31m, { roundingMode: 'up', maximumFractionDigits: 1 })
assert(a, 0.4m)
```
### JSBD.add(lhs, rhs [, options])
This function can be used as an alternative to `+` binary operator that allows rounding the result after the
calculation. It adds `rhs` and `lhs` and returns the result of such operation, applying the rounding rules
based on `options` object, if given. `options` is an options bag that configures the rounding of this
operation.
- `lhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `rhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `options`: It is an object indicating how the round operation should be performed. It's the same options bag
object described on [JSBD.round](#bigdecimalroundvalue--options). If it's not given, no rounding
operation will be applied, and the exact result will be returned.
```javascript
let a = JSBD.BigDecimal('1.25')
let b = JSBD.BigDecimal('644e-2')
// 1.25 + 6.44 = 7.69
JSBD.add(a, b).toString()
// '7.69'
```
### JSBD.subtract(lhs, rhs [, options])
This function can be used as an alternative to `-` binary operator that allows rounding the result after the
calculation. It subtracts `rhs` from `lhs` and returns the result of such operation, applying the rounding
based on `options` object, if given. `options` is an options bag that configures the rounding of this
operation.
- `lhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `rhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `options`: It is an object indicating how the round operation should be performed. It's the same options bag
object described on [JSBD.round](#bigdecimalroundvalue--options). If it's not given, no rounding
operation will be applied, and the exact result will be returned.
```javascript
let a = JSBD.BigDecimal('1.25')
let b = JSBD.BigDecimal('644e-2')
// 1.25 - 6.44 = -5.19
JSBD.subtract(a, b).toString()
// '-5.19'
```
### JSBD.multiply(lhs, rhs [, options])
This function can be used as an alternative to `*` binary operator that allows rounding the result after the
calculation. It multiplies `rhs` by `lhs` and returns the result of such operation applying the rounding based
on `options` object, if given. `options` is an options bag that configures the rounding of this operation.
- `lhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `rhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `options`: It is an object indicating how the round operation should be performed. It's the same options bag
object described on [JSBD.round](#bigdecimalroundvalue--options). If it's not given, no rounding
operation will be applied, and the exact result will be returned.
```javascript
let a = JSBD.BigDecimal('12')
let b = JSBD.BigDecimal('1.2')
// 12 * 1.2 = 14.4
JSBD.multiply(a, b).toString()
// '14.4'
```
### JSBD.divide(lhs, rhs, options)
This function is the main way to apply division using BigDecimals. It divides `lhs` by `rhs` and returns the
result of such operation applying the rounding based on `options` object. `options` is an options
bag that configures the rounding of this operation.
- `lhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `rhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `options`: It is an object indicating how the round operation should be performed. It's the same options bag
object described on [JSBD.round](#bigdecimalroundvalue--options). If it's not given, no rounding
operation will be applied, and the exact result will be returned. If the result can't be represented (due to a
non-terminating decimal expansion), it throws `TypeError`.
Different from other arithmetic operations on `BigDecimal` constructors, we require `options` for division
because this is the only operation where some results can't be represented as a `BigDecimal` value (e.g. when
we divide 1m by 3m) if we don't round. With the requirement to describe how we should round the result, it's
then possible to return a correct result for any given input.
```javascript
let a = JSBD.BigDecimal('0.2')
let b = JSBD.BigDecimal('3')
// 0.2 / 3 = 0.0067
JSBD.divide(a, b, {
maximumFractionDigits: 4,
roundingMode: 'half even',
}).toString()
// '0.0067'
```
### JSBD.remainder(lhs, rhs [, options])
This function can be used as an alternative to `%` binary operator that allows rounding the result after the
calculation. It returns the reminder of dividing `lhs` by `rhs`, applying the rounding based on `options`
object, if given. `options` is an options bag that configures the rounding of this operation.
- `lhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `rhs`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `options`: It is an object indicating how the round operation should be performed. It's the same options bag
object described on [JSBD.round](#bigdecimalroundvalue--options). If it's not given, no rounding
operation will be applied, and the exact result will be returned.
```javascript
let a = JSBD.BigDecimal('2')
let b = JSBD.BigDecimal('0.3')
// 2 % 0.3 => 0.2
JSBD.remainder(a, b).toString() // '0.2'
```
### JSBD.pow(number, power [, options])
This function returns the power of `number` by `power`, applying the rounding based on `options` object, if
given. `options` is an options bag that configures the rounding of this operation. `power` needs to be a
positive integer.
- `number`: A `BigDecimal` value. If the value is from another type, it throws `TypeError`.
- `power`: A positive integer `Number` value. If the value is from another type or not a positive integer, it
throws `RangeError`.
- `options`: It is an object indicating how the round operation should be performed. It's the same options bag
object described on [JSBD.round](#bigdecimalroundvalue--options). If it's not given, no rounding
operation will be applied, and the exact result will be returned.
```javascript
let a = JSBD.BigDecimal('0.2')
let b = 3
// '0.2^3 === 0.008'
JSBD.pow(a, b).toString()
```
### JSBD.equal(lhs, rhs)
It returns `true` if `lhs` has the same value of `rhs`. Otherwise, returns `false`.
`lhs` and `rhs` should be BigDecimal instance
```javascript
let a = JSBD.BigDecimal('0.2')
let b = JSBD.BigDecimal('2e-1')
// 'a === b
JSBD.equal(a, b) // 'true'
```
### JSBD.notEqual(lhs, rhs)
It returns `false` if `lhs` has the same value and type of `rhs`. Otherwise, returns `true`.
`lhs` and `rhs` should be BigDecimal instance
```javascript
let a = JSBD.BigDecimal('0.2')
let b = JSBD.BigDecimal('0.5')
// 'a !== b'
JSBD.notEqual(a, b) // 'true'
```
### JSBD.lessThan(lhs, rhs)
It returns `true` if the value of `lhs` is lesser than the value of `rhs`. Otherwise it returns `false`.
`lhs` and `rhs` should be BigDecimal instance
```javascript
let a = JSBD.BigDecimal('0.2')
let b = JSBD.BigDecimal('0.5')
// a < b
JSBD.lessThan(a, b) // 'true'
```
### JSBD.greaterThan(lhs, rhs)
It returns `true` if the value of `lhs` is greater than the value of `rhs`. Otherwise it returns `false`.
`lhs` and `rhs` should be BigDecimal instance
```javascript
let a = JSBD.BigDecimal('0.9')
let b = JSBD.BigDecimal('0.5')
// a > b
JSBD.greaterThan(a, b) // 'true'
```
### JSBD.lessThanOrEqual(lhs, rhs)
It returns `true` if the value of `lhs` is lesser or equal than the value of `rhs`. Otherwise, it returns `false`.
`lhs` and `rhs` should be BigDecimal instance
```javascript
let a = JSBD.BigDecimal('0.1')
let b = JSBD.BigDecimal('0.4')
// a <= b
JSBD.lessThanOrEqual(a, b) // 'true'
```
### JSBD.greaterThanOrEqual(lhs, rhs)
It returns `true` if the value of `lhs` is greater or equal than the value of `rhs`. Otherwise, it returns `false`.
`lhs` and `rhs` should be BigDecimal instance
```javascript
let a = JSBD.BigDecimal('0.5')
let b = JSBD.BigDecimal('0.4')
// a >= b
JSBD.greaterThanOrEqual(a, b) // 'true'
```
## BigDecimal prototype
`BigDecimal.prototype` includes utility methods used to help manipulation of `BigDecimal` values.
### `BigDecimal.prototype.toString()`
This method returns a string that represents the `BigDecimal` value.
```js
let v = JSBD.BigDecimal('0.55')
console.log(v.toString()) // prints "0.55"
```
### `BigDecimal.prototype.toFixed([digits])`
This function returns a string that represents fixed-point notation of the `BigDecimal` value. There is an
optional parameter `digits` that defines the number of digits after decimal point. It follows the same
semantics of `Number.prototype.toFixed`.
```js
let v = JSBD.BigDecimal('100.456')
console.log(v.toFixed(2)) // prints 100.46
let v = JSBD.BigDecimal('0')
console.log(v.toFixed(2)) // prints 0.00
```
### `BigDecimal.prototype.toExponential([fractionDigits])`
This methods returns a string of the `BigDecimal` in exponential representation. It takes an optional
parameter `fractionDigits` that defines the number of digits after decimal point. It follows the same
semantics of `Number.prototype.toExponential`.
```js
let v = JSBD.BigDecimal('1010')
console.log(v.toExponential(2)) // prints 1.01e+3
```
### `BigDecimal.prototype.toPrecision([precision])`
This function returns a string that represents the `BigDecimal` in the specified precision. It follows the
same semantics of `Number.prototype.toPrecision`.
```js
let v = JSBD.BigDecimal('111.22')
console.log(v.toPrecision()) // prints 111.22
console.log(v.toPrecision(4)) // 111.2
console.log(v.toPrecision(2)) //1.1e+2
```
## for developer
since test use es module in node , better use node >= 14
```
yarn install
// change source code and add test case
yarn test
```