big.js、bignumber.js 和 decimal.js 之间的差别(翻译)

4,200 阅读2分钟

原文链接:What is the difference between big.js, bignumber.js and decimal.js?

big.js 是最小的任意精度的计算库。big.js 是三者中最小也最简单的,它只有 bignumber.js 一半的方法,不到 bignumber.js 的一半大。big.js 中,NAN 或者 Infinity 是不合法值,它不能处理除了十进制以外的其它进制。运行时的配置项仅限于设置小数位数、包含除法在内的四舍五入的运算模式,以及 toString 生成的科学计数法的指数值。

Big.DP = 7;             // 最大小数位数
Big.RM = 4;             // round half-up
var x = new Big(5);
x.div(3).toString();    // '1.6666667' 

这三个库都包含了 JavaScript 中 Number 类型的 toExponentialtoFixedtoPrecision 方法。

bignumber.jsdecimal.js 存储值的进制比 big.js 更高,因此当操作大量数字时,前两者的速度会更快。

bignumber.jsdecimal.js 也支持其它进制的计算,并支持前缀,比如十六进制的 0xdecimal.js 还可以使用二进制指数表示法处理二进制、八进制和十六进制,C 语言中就是如此。

var x = new BigNumber('ff.8', 16);
x.toString();          // '255.5'
x.toString(16);        // 'ff.8'

var x = new Decimal('0xff.8');
x.toString();          // '255.5'
x.toHexadecimal();     // '0xff.8'
x.toHex(3);            // '0x1.ffp+7'

decimal.js 最初是通过向 bignumber.js 添加对非整数次幂的支持来开发的,但后续我决定将它作为一个单独的库来发布。二者最主要的区别在于,decimal.js 的精度是以有效数字而不是小数位数来指定的,并且所有的计算都舍入到该精度(类似于 Python 的小数模块),而不是只有涉及到除法的运算。

Bignumber.config({ DECIMAL_PLACES: 3, ROUNDING_MODE; 1 });
var x = new BigNumber('123.456789');
x.plus(1).toString();    // '124.456789'

Decimal.set({ precision: 7, rounding: 4 });
var y = new Decimal('123.456789');
y.plus(1).toString();    // '124.4568'

bignumber.js 可能更适合金融类应用,因为用户不用担心丢失精度,除非使用了涉及除法的操作。

对于科学类应用来说,decimal.js 可能更好,因为它可以更有效的处理非常小或者非常大的数值。例如,它没有 bignumber.js 的限制,即当将一个小指数值和一个大指数值相加时,bignumber.js 将使用完全精度来操作,时间上来看不可行。

如上所述,decimal.js 还支持非整数次幂、三角函数、exp、ln、log 方法。这些额外的方法使得 decimal.jsbignumber.js 大得多。

  • big.js 最小最简;便于使用;精度采用小数位;精度仅适用除法;4种舍入模式。
  • bignumber.js 配置选项;NaN;Infinity;精度采用小数位;精度仅适用于除法;随机数字;进制转换;9种舍入模式;模模式;模幂运算。
  • decimal.js 配置选项;NaN;Infinity;非整数次幂,exp,ln,log;三角函数;精度采用有效数字;所有操作均采取精度;随机数字;9种舍入模式;模模式;二进制,八进制,十六进制;二进制指数符号。