一个用于任意精度小数和非小数运算的 JavaScript 库
地址:https://github.com/MikeMcl/bignumber.js
功能
- 整数和小数
- 简单的 API,但功能齐全
- 比 Java 的 BigDecimal 的 JavaScript 版本更快、更小,而且可能更容易使用
- 大小只有8 KB
- 支持密码安全的伪随机数生成
- 没有依赖性
- 广泛的平台兼容性: 仅使用 JavaScript 1.5(ECMAScript 3)特性
浏览器:
<script src='path/to/bignumber.js'></script>
Node.js
$ npm install bignumber.js
const BigNumber = require('bignumber.js');
import BigNumber from "bignumber.js";
// or
import { BigNumber } from "bignumber.js";
使用
单个构造函数 BigNumber,该函数接受 Number、 String 或 BigNumber 类型的值,
let x = new BigNumber(123.4567);
let y = BigNumber('123456.7e-3');
let z = new BigNumber(x);
x.isEqualTo(y) && y.isEqualTo(z) && x.isEqualTo(z); // true
要获取 BigNumber 的字符串值,可以使用 toString ()或 toFixed ()。使用 toFixed ()可以防止返回指数表示法,无论值有多大或多小。
let x = new BigNumber('1111222233334444555566');
x.toString(); // "1.111222233334444555566e+21"
x.toFixed(); // "1111222233334444555566"
如果没有很好地理解 Number 值的有限精度,建议从 String 值而不是 Number 值创建 BigNumbers,以避免可能的精度损失。
在下面所有进一步的示例中,不显示分号和 toString 调用。如果注释掉的值在引号中,则表示对前面的表达式调用了 toString。
// Precision loss from using numeric literals with more than 15 significant digits.
new BigNumber(1.0000000000000001) // '1'
new BigNumber(88259496234518.57) // '88259496234518.56'
new BigNumber(99999999999999999999) // '100000000000000000000'
// Precision loss from using numeric literals outside the range of Number values.
new BigNumber(2e+308) // 'Infinity'
new BigNumber(1e-324) // '0'
// Precision loss from the unexpected result of arithmetic with Number values.
new BigNumber(0.7 + 0.1) // '0.7999999999999999'
从 Number 创建 BigNumber 时,请注意 BigNumber 是从 Number 的十进制 toString ()值创建的,而不是从其基础二进制值创建的。如果需要后者,则传递 Number 的 toString (2)值并指定 base 2。
new BigNumber(Number.MAX_VALUE.toString(2), 2)
BigNumbers 可以从2到36的基数值中创建。请参见 ALPHABET 以扩展这个范围。
a = new BigNumber(1011, 2) // "11"
b = new BigNumber('zz.9', 36) // "1295.25"
c = a.plus(b) // "1306.25"
如果不为十进制值指定基数10,性能会更好。只有当您希望将输入值的小数位数限制为当前 DECIMAL _ places 设置时,才指定 base 10。
BigNumber 是不可变的,因为它的方法不会改变它。
0.3 - 0.1 // 0.19999999999999998
x = new BigNumber(0.3)
x.minus(0.1) // "0.2"
x // "0.3"
返回 BigNumber 的方法可以链接起来。
x.dividedBy(y).plus(z).times(9)
x.times('1.23456780123456789e+9').plus(9876.5432321).dividedBy('4444562598.111772').integerValue()
一些较长的方法名有较短的别名。
x.squareRoot().dividedBy(y).exponentiatedBy(3).isEqualTo(x.sqrt().div(y).pow(3)) // true
x.modulo(y).multipliedBy(z).eq(x.mod(y).times(z)) // true
和 JavaScript 的 Number 类型一样,有 toExponential、 toFixed 和 toPrecision 方法。
x = new BigNumber(255.5)
x.toExponential(5) // "2.55500e+2"
x.toFixed(5) // "255.50000"
x.toPrecision(5) // "255.50"
x.toNumber() // 255.5
可以为 toString 指定基。
如果没有指定基数10,性能会更好,即使用 toString ()而不是 toString (10)。只有当您希望将字符串的小数位数限制为当前 DECIMAL _ places 设置时,才指定 base 10。
x.toString(16) // "ff.8"
有一个 toFormat 方法可能对国际化很有用。
y = new BigNumber('1234567.898765')
y.toFormat(2) // "1,234,567.90"
使用 BigNumber 构造函数的 set 或 config 方法设置涉及除法(即除法、平方根、基转换或负功率运算)的运算结果的最大小数位数。
其他的算术运算总是给出精确的结果。
BigNumber.set({ DECIMAL_PLACES: 10, ROUNDING_MODE: 4 })
x = new BigNumber(2)
y = new BigNumber(3)
z = x.dividedBy(y) // "0.6666666667"
z.squareRoot() // "0.8164965809"
z.exponentiatedBy(-3) // "3.3749999995"
z.toString(2) // "0.1010101011"
z.multipliedBy(z) // "0.44444444448888888889"
z.multipliedBy(z).decimalPlaces(10) // "0.4444444445"
有一个带有可选最大分母参数的 toFraction 方法
y = new BigNumber(355)
pi = y.dividedBy(113) // "3.1415929204"
pi.toFraction() // [ "7853982301", "2500000000" ]
pi.toFraction(1000) // [ "355", "113" ]
以及 isNaN 和 isFinite 方法,因为 NaN 和 Infinity 是有效的 BigNumber 值。
x = new BigNumber(NaN) // "NaN"
y = new BigNumber(Infinity) // "Infinity"
x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite() // true
BigNumber 的值以系数、指数和符号的十进制浮点格式存储。
x = new BigNumber(-123.456);
x.c // [ 123, 45600000000000 ] coefficient (i.e. significand)
x.e // 2 exponent
x.s // -1 sign
对于高级用法,可以创建多个 BigNumber 构造函数,每个构造函数都有自己的独立配置。
// Set DECIMAL_PLACES for the original BigNumber constructor
BigNumber.set({ DECIMAL_PLACES: 10 })
// Create another BigNumber constructor, optionally passing in a configuration object
BN = BigNumber.clone({ DECIMAL_PLACES: 5 })
x = new BigNumber(1)
y = new BN(1)
x.div(3) // '0.3333333333'
y.div(3) // '0.33333'
为了避免在 BigNumber 上调用 toString 或 valueOf 来获取其在 Node.js REPL 中的值,或者在使用 console.log 时使用
BigNumber.prototype[require('util').inspect.custom] = BigNumber.prototype.valueOf;