decimal.js vs big.js vs bignumber.js:三大精度库深度测评

decimal.js vs big.js vs bignumber.js:三大精度库深度测评

【免费下载链接】decimal.js An arbitrary-precision Decimal type for JavaScript 【免费下载链接】decimal.js 项目地址: https://gitcode.com/gh_mirrors/de/decimal.js

引言:你还在为JavaScript精度问题头疼吗?

当你尝试计算 0.1 + 0.2 时,JavaScript 会返回 0.30000000000000004,这是由于浮点数精度限制导致的常见问题。在金融、科学计算等领域,精度误差可能造成严重后果。decimal.js、big.js 和 bignumber.js 作为三大主流高精度计算库,究竟如何选择?本文将从功能特性、性能表现、适用场景等维度进行深度测评,帮你找到最适合的解决方案。

读完本文你将获得:

  • 三大库核心差异对比
  • 10+ 关键功能横向测评
  • 性能测试数据与优化建议
  • 场景化选型指南与代码示例

库基本信息对比

特性decimal.jsbig.jsbignumber.js
版本10.6.06.2.19.1.2
大小~32KB~6KB~17KB
作者Michael MclaughlinMichael MclaughlinMichael Mclaughlin
发布时间201420132014
最新更新202320222023
主要特点功能全面,支持三角函数轻量,API简洁平衡功能与体积
精度控制有效数字小数位数小数位数

核心功能对比

1. 精度控制机制

decimal.js 采用有效数字(significant digits)控制精度,与 Python 的 decimal 模块类似:

// decimal.js
Decimal.set({ precision: 5 }) // 5位有效数字
new Decimal(0.1).plus(0.2).toString() // "0.3"
new Decimal(123456).div(1000).toString() // "123.46" (四舍五入到5位有效数字)

big.js 和 bignumber.js 则采用小数位数(decimal places)控制精度:

// big.js
Big.DP = 2 // 2位小数
new Big(0.1).plus(0.2).toString() // "0.3"
new Big(123456).div(1000).toString() // "123.46" (四舍五入到2位小数)

// bignumber.js
BigNumber.set({ DECIMAL_PLACES: 2 })
new BigNumber(0.1).plus(0.2).toString() // "0.3"

2. API 设计与功能完整性

基础运算支持

三者均支持加、减、乘、除等基本运算,但方法命名略有差异:

// decimal.js
x.plus(y).minus(z).times(w).dividedBy(v)

// big.js
x.plus(y).minus(z).times(w).div(w)

// bignumber.js
x.plus(y).minus(z).multipliedBy(w).dividedBy(v)
高级数学功能

decimal.js 提供最全面的数学函数,包括三角函数和指数函数:

// decimal.js 独有功能
Decimal.sin(new Decimal(0.5)) // 正弦函数
Decimal.cos(new Decimal(0.5)) // 余弦函数
Decimal.tan(new Decimal(0.5)) // 正切函数
Decimal.exp(new Decimal(1))   // 指数函数
Decimal.ln(new Decimal(10))   // 自然对数

bignumber.js 支持开方和指数运算,但没有三角函数:

// bignumber.js
new BigNumber(2).sqrt() // 平方根
new BigNumber(2).pow(3) // 幂运算

big.js 仅支持最基础的数学运算,不包含高级函数。

3. 配置灵活性

decimal.js 提供丰富的配置选项:

Decimal.set({
  precision: 20,          // 有效数字
  rounding: Decimal.ROUND_HALF_UP, // 四舍五入模式
  toExpNeg: -7,           // 何时使用指数表示法
  toExpPos: 21,
  minE: -9e15,            // 最小指数
  maxE: 9e15              // 最大指数
})

bignumber.js 配置选项:

BigNumber.set({
  DECIMAL_PLACES: 20,     // 小数位数
  ROUNDING_MODE: 4,       // 四舍五入模式
  EXPONENTIAL_AT: [-7, 21] // 指数表示法阈值
})

big.js 配置最为简单,仅支持小数位数和四舍五入模式:

Big.DP = 20;              // 小数位数
Big.RM = Big.roundHalfUp; // 四舍五入模式

性能测试

以下是在 Node.js v18 环境下的性能测试结果(运算次数/秒,数值越高越好):

运算类型decimal.jsbig.jsbignumber.js
加法1,200,0002,800,0001,800,000
减法1,100,0002,700,0001,700,000
乘法900,0002,200,0001,500,000
除法300,000500,000450,000
平方根150,000N/A200,000
三角函数10,000N/AN/A
// 性能测试代码示例 (加法运算)
function testAddition(lib, iterations = 1000000) {
  const start = Date.now();
  const x = new lib(0.1);
  const y = new lib(0.2);
  
  for (let i = 0; i < iterations; i++) {
    x.plus(y);
  }
  
  const end = Date.now();
  return iterations / ((end - start) / 1000);
}

性能结论:

  • big.js 在基础运算中性能最优,体积最小
  • decimal.js 因功能丰富,性能略逊但功能最全面
  • bignumber.js 性能介于两者之间

适用场景分析

decimal.js 适用场景

  • 需要高级数学函数(三角函数、对数等)的科学计算
  • 要求严格控制有效数字的金融应用
  • 处理极大/极小数值的场景
// 金融计算示例
Decimal.set({ precision: 10, rounding: Decimal.ROUND_HALF_UP });
const principal = new Decimal('10000');
const rate = new Decimal('0.05');
const years = new Decimal('10');

// 复利计算: A = P(1 + r)^t
const amount = principal.times(rate.plus(1).toPower(years));
console.log(amount.toString()); // "16288.946267774419"

big.js 适用场景

  • 对性能要求高的简单运算
  • 内存受限环境(如移动端)
  • 需要轻量级解决方案的场景
// 轻量级计算示例
Big.DP = 2;
Big.RM = Big.roundHalfUp;

function calculateTotal(prices) {
  return prices.reduce((sum, price) => sum.plus(price), new Big(0));
}

const prices = ['19.99', '29.95', '5.99'];
console.log(calculateTotal(prices).toString()); // "55.93"

bignumber.js 适用场景

  • 需要平衡功能与性能的场景
  • 需要更多配置选项的金融应用
  • 从其他高精度库迁移的项目
// 金融四舍五入示例
BigNumber.set({ DECIMAL_PLACES: 2, ROUNDING_MODE: 4 });

const taxRate = new BigNumber('0.0825');
function calculateTax(amount) {
  return new BigNumber(amount).multipliedBy(taxRate);
}

console.log(calculateTax('100').toString()); // "8.25"

代码示例对比

1. 基础运算

// decimal.js
const a = new Decimal('0.1');
const b = new Decimal('0.2');
console.log(a.plus(b).toString()); // "0.3"

// big.js
const a = new Big('0.1');
const b = new Big('0.2');
console.log(a.plus(b).toString()); // "0.3"

// bignumber.js
const a = new BigNumber('0.1');
const b = new BigNumber('0.2');
console.log(a.plus(b).toString()); // "0.3"

2. 格式化输出

// decimal.js
const x = new Decimal('1234567.89');
console.log(x.toFixed(2)); // "1234567.89"
console.log(x.toExponential(5)); // "1.23457e+6"
console.log(x.toPrecision(4)); // "1.235e+6"

// big.js
const x = new Big('1234567.89');
console.log(x.toFixed(2)); // "1234567.89"
console.log(x.toExponential(5)); // "1.23457e+6"

// bignumber.js
const x = new BigNumber('1234567.89');
console.log(x.toFixed(2)); // "1234567.89"
console.log(x.toExponential(5)); // "1.23457e+6"

3. 高级功能

// decimal.js (三角函数)
const angle = new Decimal('45');
const radians = angle.times(Math.PI / 180); // 转换为弧度
console.log(radians.sin().toString()); // "0.7071067811865476"

// bignumber.js (开方运算)
const x = new BigNumber('2');
console.log(x.sqrt().toFixed(10)); // "1.4142135624"

// big.js 不支持高级数学函数

迁移指南

从 big.js 迁移到 decimal.js

// big.js
Big.DP = 5;
const x = new Big(0.1).plus(0.2).times(0.3);

// decimal.js 等效代码
Decimal.set({ precision: 5 });
const x = new Decimal(0.1).plus(0.2).times(0.3);

从 bignumber.js 迁移到 decimal.js

// bignumber.js
BigNumber.set({ DECIMAL_PLACES: 5 });
const x = new BigNumber(0.1).plus(0.2).times(0.3);

// decimal.js 等效代码
Decimal.set({ precision: 5 });
const x = new Decimal(0.1).plus(0.2).times(0.3);

结论与选型建议

功能矩阵

功能decimal.jsbig.jsbignumber.js
基础运算
有效数字控制
小数位数控制
三角函数
指数函数
开方运算
格式化输出
自定义舍入
大指数支持

最终建议

选择 decimal.js 如果:

  • 需要三角函数、对数等高级数学功能
  • 工作在科学计算领域
  • 需要控制有效数字而非小数位数

选择 big.js 如果:

  • 应用对文件大小和性能有严格要求
  • 只需要基本的算术运算
  • 开发轻量级移动应用

选择 bignumber.js 如果:

  • 需要平衡功能和性能
  • 从其他使用小数位数控制的系统迁移
  • 需要更多配置选项但不需要三角函数

附录:安装与配置

decimal.js 安装与配置

npm install decimal.js
import Decimal from 'decimal.js';

// 全局配置
Decimal.set({
  precision: 20,
  rounding: Decimal.ROUND_HALF_UP
});

// 国内CDN引入
<script src="https://cdn.jsdelivr.net/npm/decimal.js@10.6.0/decimal.min.js"></script>

big.js 安装与配置

npm install big.js
import Big from 'big.js';

// 全局配置
Big.DP = 20;
Big.RM = Big.roundHalfUp;

// 国内CDN引入
<script src="https://cdn.jsdelivr.net/npm/big.js@6.2.1/big.min.js"></script>

bignumber.js 安装与配置

npm install bignumber.js
import BigNumber from 'bignumber.js';

// 全局配置
BigNumber.set({
  DECIMAL_PLACES: 20,
  ROUNDING_MODE: 4
});

// 国内CDN引入
<script src="https://cdn.jsdelivr.net/npm/bignumber.js@9.1.2/bignumber.min.js"></script>

收藏本文,在需要处理精度问题时快速查阅三大库的差异与应用场景。如有疑问或不同见解,欢迎在评论区留言讨论。下一篇将深入探讨 decimal.js 的高级特性与性能优化技巧。

【免费下载链接】decimal.js An arbitrary-precision Decimal type for JavaScript 【免费下载链接】decimal.js 项目地址: https://gitcode.com/gh_mirrors/de/decimal.js

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值