为什么选择 a-calc
一句话总结
a-calc 是地表最强的 JavaScript 精度计算和数字格式化库。
不是之一,没有并列。
精度问题:JavaScript 的原罪
javascript
// JavaScript 原生计算
0.1 + 0.2 // 0.30000000000000004
0.3 - 0.1 // 0.19999999999999998
0.1 * 0.2 // 0.020000000000000004
0.3 / 0.1 // 2.9999999999999996这在金融、电商、数据报表等场景是致命的。
javascript
// a-calc 的答案
import { calc } from 'a-calc'
calc('0.1 + 0.2') // '0.3'
calc('0.3 - 0.1') // '0.2'
calc('0.1 * 0.2') // '0.02'
calc('0.3 / 0.1') // '3'性能:10 倍碾压
| 库 | 50 万次计算 | 相对性能 |
|---|---|---|
| a-calc | 3.6s | 10x |
| mathjs v13 | 5.7s | 1.6x |
| mathjs v12 | 36s | 1x (基准) |
这不是优化,是代差。
功能:一个顶三个
| 功能 | a-calc | mathjs | numeral | decimal.js |
|---|---|---|---|---|
| 精度计算 | ✅ | ✅ | ❌ | ✅ |
| 表达式解析 | ✅ | ✅ | ❌ | ❌ |
| 千分位格式化 | ✅ | ❌ | ✅ | ❌ |
| 百分比格式化 | ✅ | ❌ | ✅ | ❌ |
| 国际化数字格式 | ✅ | ❌ | ❌ | ❌ |
| 紧凑格式缩写 | ✅ | ❌ | ✅ | ❌ |
| 单位计算 | ✅ | ✅ | ❌ | ❌ |
| 单位转换 | ✅ | ✅ | ❌ | ❌ |
| 条件表达式 | ✅ | ❌ | ❌ | ❌ |
| 链式计算 | ✅ | ❌ | ❌ | ✅ |
| 表达式预编译 | ✅ | ❌ | ❌ | ❌ |
| 多计算引擎 | ✅ | ❌ | ❌ | ❌ |
| 包大小 | 20KB | 150KB | 18KB | 12KB |
mathjs + numeral + decimal.js = 180KB,功能还不如 a-calc 的 20KB。
核心能力一览
1. 计算 + 格式化一步到位
javascript
// 其他库:计算完还要格式化
const result = mathjs.evaluate('price * quantity')
const formatted = numeral(result).format('0,0.00')
// a-calc:一行搞定
calc('price * quantity | =2,', { price: 1234.5, quantity: 2 })
// '2,469.00'2. 四种舍入规则
javascript
calc('1.125 | ~-=2') // '1.12' - 截断
calc('1.125 | ~+=2') // '1.13' - 进位
calc('1.125 | ~5=2') // '1.13' - 四舍五入
calc('1.125 | ~6=2') // '1.12' - 银行家舍入(四舍六入五取偶)银行家舍入是金融行业标准,其他库要么不支持,要么需要额外配置。
3. 全球数字格式
javascript
calc('1234567.89 | !t:en') // '1,234,567.89' 英文/国际
calc('1234567.89 | !t:eu') // '1.234.567,89' 欧式
calc('1234567.89 | !t:indian') // '12,34,567.89' 印度
calc('1234567.89 | !t:wan') // '1,2345,678.89' 万进制4. 紧凑格式智能缩写
javascript
calc('1234567 | !c') // '1.23M'
calc('12345 | !c:wan') // '1.23万'
calc('1073741824 | !c:storage') // '1GB'5. 三种计算引擎
javascript
import { set_config, calc } from 'a-calc'
// Decimal 模式:50 位精度,功能最全
set_config({ _compute_mode: 'decimal' })
// BigInt 模式:大整数无损,性能更好
set_config({ _compute_mode: 'bigint' })
calc('12345678901234567890 * 2') // 完全精确
// WASM 模式:极致性能
set_config({ _compute_mode: 'wasm' })6. 链式计算
javascript
import { cplus, cmul } from 'a-calc'
// 购物车计算
cplus(99.9, 199, 49.5) // 商品价格
.mul(0.9) // 9折
.sub(20) // 满减
.mul(1.06) // 税费
('=2,') // '296.33'7. 条件表达式
javascript
calc('score >= 60 ? "及格" : "不及格"', { score: 75 }) // '及格'
calc(`
score >= 90 ? "A" :
score >= 80 ? "B" :
score >= 70 ? "C" :
score >= 60 ? "D" : "F"
`, { score: 85 }) // 'B'8. 单位计算与转换
javascript
// 带单位计算
calc('100元 + 50元', { _unit: true }) // '150元'
// 单位转换
calc('100 | !ua:元', {
_unit_convert_out: { '元': { '分': 0.01 } }
}) // '1元' (100分 → 1元)9. 内置数学函数
javascript
calc('sqrt(16)') // '4'
calc('sin(90)') // '1' (默认角度制)
calc('pow(2, 10)') // '1024'
calc('max(1, 5, 3)') // '5'
calc('round(3.7)') // '4'
calc('abs(-5)') // '5'10. 多路取值(Fallback)
javascript
// 优先取 a,a 为空则取 b
calc('(a | b) + 1', { b: 10 }) // '11'
calc('(a | b) + 1', { a: 5, b: 10 }) // '6'
// 多级 fallback
calc('(a | b | c)', { c: 100 }) // '100'11. 调试模式
javascript
calc('a + b * c', { a: 1, b: 2, c: 3, _debug: true })
// 控制台输出完整的计算过程和中间结果实战场景
金融计算
javascript
// 复利计算
calc('principal * pow(1 + rate, years) | =2,', {
principal: 10000,
rate: 0.05,
years: 3
}) // '11,576.25'
// 银行家舍入
calc('amount | ~6=2', { amount: 2.225 }) // '2.22'
calc('amount | ~6=2', { amount: 2.235 }) // '2.24'电商价格
javascript
// 满减 + 折扣
calc('(price * quantity - fullCut) * discount | =2', {
price: 199,
quantity: 3,
fullCut: 50,
discount: 0.9
}) // '491.10'数据报表
javascript
// 批量格式化
const data = [1234567, 2345678, 3456789]
data.map(n => calc(`${n} | =2,`))
// ['1,234,567.00', '2,345,678.00', '3,456,789.00']
// 涨跌幅
calc('change | %=2+', { change: 0.0523 }) // '+5.23%'
calc('change | %=2+', { change: -0.0312 }) // '-3.12%'股票交易量
javascript
calc('volume | !c:wan', { volume: 12345678 }) // '1234.56万'
calc('volume | !c !ua:股', { volume: 1234567 }) // '1.23M股'迁移成本:几乎为零
javascript
// 从 mathjs 迁移
// Before
mathjs.evaluate('1 + 2 * 3')
// After
calc('1 + 2 * 3')
// 从 numeral 迁移
// Before
numeral(1234567).format('0,0.00')
// After
calc('1234567 | =2,')
// 从 decimal.js 迁移
// Before
new Decimal('0.1').plus('0.2').toString()
// After
calc('0.1 + 0.2')总结
| 维度 | a-calc 的答案 |
|---|---|
| 精度 | 50 位 Decimal / 无限 BigInt / 28 位 WASM |
| 性能 | 比 mathjs 快 10 倍 |
| 体积 | 20KB,比 mathjs 小 7 倍 |
| 格式化 | 千分位、百分比、科学计数、紧凑格式、国际化 |
| 舍入 | 截断、进位、四舍五入、银行家舍入 |
| 易用性 | 计算 + 格式化一行代码 |
a-calc 不是在某个维度上领先,而是在所有维度上碾压。
这就是为什么选择 a-calc。