Skip to content

金融计算

金融场景对精度要求极高,a-calc 能完美解决 JavaScript 浮点数精度问题。

利息计算

单利计算

javascript
import { calc } from 'a-calc'

// 单利公式:利息 = 本金 × 利率 × 期限
const interest = calc('principal * rate * years | =2', {
  principal: 100000,  // 本金 10万
  rate: 0.045,        // 年利率 4.5%
  years: 3            // 3年
})
// '13500.00'

// 本息合计
const total = calc('principal * (1 + rate * years) | =2,', {
  principal: 100000,
  rate: 0.045,
  years: 3
})
// '113,500.00'
Ctrl+D 选择词, Ctrl+/ 注释

复利计算

javascript
import { calc } from 'a-calc'

// 复利公式:本息 = 本金 × (1 + 利率)^期数
const compound = calc('principal * (1 + rate) ** years | =2,', {
  principal: 100000,
  rate: 0.045,
  years: 3
})
// '114,116.61'

// 复利收益
const profit = calc('principal * ((1 + rate) ** years - 1) | =2,', {
  principal: 100000,
  rate: 0.045,
  years: 3
})
// '14,116.61'

汇率转换

javascript
import { calc } from 'a-calc'

// 美元转人民币
const cny = calc('usd * rate | =2', {
  usd: 1000,
  rate: 7.2456
})
// '7245.60'

// 批量转换
const amounts = [100, 500, 1000, 5000]
const converted = amounts.map(usd =>
  calc('usd * rate | =2,', { usd, rate: 7.2456 })
)
// ['724.56', '3,622.80', '7,245.60', '36,228.00']
Ctrl+D 选择词, Ctrl+/ 注释

贷款计算

等额本息

javascript
import { calc } from 'a-calc'

// 月供 = [贷款本金×月利率×(1+月利率)^还款月数] ÷ [(1+月利率)^还款月数-1]
function calcMonthlyPayment(principal, annualRate, months) {
  const monthlyRate = calc('rate / 12', { rate: annualRate })

  return calc(`
    principal * mr * (1 + mr) ** months /
    ((1 + mr) ** months - 1) | ~5=2
  `, {
    principal,
    mr: monthlyRate,
    months
  })
}

// 贷款100万,年利率4.9%,30年
const monthly = calcMonthlyPayment(1000000, 0.049, 360)
// '5307.27'

等额本金

javascript
import { calc } from 'a-calc'

// 每月还款 = (本金/期数) + 剩余本金×月利率
function calcPrincipalPayment(principal, annualRate, months, currentMonth) {
  const monthlyRate = calc('rate / 12', { rate: annualRate })
  const monthlyPrincipal = calc('principal / months', { principal, months })
  const remainingPrincipal = calc(
    'principal - monthlyPrincipal * (currentMonth - 1)',
    { principal, monthlyPrincipal, currentMonth }
  )

  return calc('monthlyPrincipal + remaining * rate | =2', {
    monthlyPrincipal,
    remaining: remainingPrincipal,
    rate: monthlyRate
  })
}

// 第1期还款
calcPrincipalPayment(1000000, 0.049, 360, 1)   // '6861.11'
// 第12期还款
calcPrincipalPayment(1000000, 0.049, 360, 12)  // '6823.61'

投资收益

年化收益率

javascript
import { calc } from 'a-calc'

// 年化收益率 = (期末净值/期初净值 - 1) × 100%
const annualReturn = calc('(end / start - 1) * 100 | ~5=2', {
  start: 1.0000,
  end: 1.0856
})
// '8.56' (8.56%)

定投收益

javascript
import { calc, calc_sum } from 'a-calc'

// 模拟12个月定投
const investments = [
  { month: 1, amount: 1000, nav: 1.00 },
  { month: 2, amount: 1000, nav: 0.95 },
  { month: 3, amount: 1000, nav: 1.02 },
  // ... 更多月份
]

// 计算总份额
const totalShares = calc_sum('amount / nav | =4', investments)

// 计算总投入
const totalInvest = calc_sum('amount', investments)

// 当前净值计算市值
const currentNav = 1.08
const marketValue = calc('shares * nav | =2', {
  shares: totalShares,
  nav: currentNav
})

税费计算

个人所得税

javascript
import { calc } from 'a-calc'

// 简化的个税计算(不考虑专项扣除)
function calcIncomeTax(income) {
  const taxable = calc('income - 5000', { income })  // 起征点5000

  if (calc(`${taxable} <= 0 | !n`)) return '0.00'

  // 根据税率表计算
  const brackets = [
    { limit: 3000, rate: 0.03, deduction: 0 },
    { limit: 12000, rate: 0.10, deduction: 210 },
    { limit: 25000, rate: 0.20, deduction: 1410 },
    { limit: 35000, rate: 0.25, deduction: 2660 },
    { limit: 55000, rate: 0.30, deduction: 4410 },
    { limit: 80000, rate: 0.35, deduction: 7160 },
    { limit: Infinity, rate: 0.45, deduction: 15160 }
  ]

  const bracket = brackets.find(b =>
    calc(`${taxable} <= ${b.limit} | !n`)
  )

  return calc('taxable * rate - deduction | =2', {
    taxable,
    rate: bracket.rate,
    deduction: bracket.deduction
  })
}

calcIncomeTax(10000)   // '150.00'
calcIncomeTax(20000)   // '1590.00'
calcIncomeTax(50000)   // '8490.00'

银行家舍入

金融计算推荐使用 ~6(四舍六入五取偶)舍入规则:

javascript
import { calc } from 'a-calc'

// 四舍六入五取偶,最精确的舍入方式
calc('1.125 | ~6=2')    // '1.12' (5前面是2,偶数,舍)
calc('1.135 | ~6=2')    // '1.14' (5前面是3,奇数,入)
calc('1.145 | ~6=2')    // '1.14' (5前面是4,偶数,舍)
calc('1.155 | ~6=2')    // '1.16' (5前面是5,奇数,入)

// 当5后面还有数字时,总是进位
calc('1.1251 | ~6=2')   // '1.13'
calc('1.1350 | ~6=2')   // '1.14'
Ctrl+D 选择词, Ctrl+/ 注释

紧凑格式显示

使用 !c 格式化交易量,自动转换为 K/M/B/T 格式:

javascript
import { calc } from 'a-calc'

// 股票交易量显示
calc('1234567 | !c')           // '1.23M'
calc('1234567890 | !c')        // '1.23B'
calc('999 | !c')               // '999' (小于1000不转换)

// 带正负号的涨跌幅
calc('1234567 | +!c')          // '+1.23M'
calc('-1234567 | +!c')         // '-1.23M'

// 指定小数位数
calc('1234567 | !c =1')        // '1.2M'
calc('1234567 | !c =0')        // '1M'

// 自定义单位(中文)
calc('1234567 | !c', {
  _compact_symbols: ["", "千", "百万", "十亿"]
})  // '1.23百万'
Ctrl+D 选择词, Ctrl+/ 注释

货币符号格式化

使用 !um:unit 将货币符号放在正负号和数字之间(middle 位置):

javascript
import { calc } from 'a-calc'

// 涨跌显示
calc('1234.56 | + !um:$')   // '+$1234.56'
calc('-567.89 | + !um:$')   // '-$567.89'

// 结合千分位和小数格式化
calc('12345.6 | +=2, !um:$')  // '+$12,345.60'

// 不同货币
calc('100 | + !um:¥')     // '+¥100'
calc('100 | + !um:€')     // '+€100'
calc('100 | + !um:USD')   // '+USD100'

单位位置语法

a-calc 提供三种单位位置语法:

javascript
import { calc } from 'a-calc'

// !ua:unit - 单位在数字后 (after)
calc('100 | !ua:元')          // '100元'
calc('1234.5 | =2, !ua:元')   // '1,234.50元'

// !ub:unit - 单位在数字前 (before)
calc('100 | !ub:$')           // '$100'
calc('-50 | !ub:$')           // '$-50'

// !um:unit - 单位在中间 (middle),符号后数字前
calc('100 | + !um:$')         // '+$100'
calc('-50 | + !um:$')         // '-$50'

单位转换配置

除了语法,还可以通过配置项进行单位格式化和转换:

javascript
import { calc } from 'a-calc'

// 配置单位转换(分转元)
calc('10000 | =2', {
  _unit_convert_out: { '元': { '分': 0.01 } },
  _unit_default_out: '元',
  _unit_default_position: 'after'
})  // '100.00元'

// 使用 !u: 语法(推荐,简洁)
calc('10000 | =2 !u:元', {
  _unit_convert_out: { '元': { '分': 0.01 } }
})  // '100.00元'

// 使用 !uh: 只转换不显示单位
calc('10000 | =2 !uh:元', {
  _unit_convert_out: { '元': { '分': 0.01 } }
})  // '100.00'

// 使用 @ 变量引用单位
calc('10000 | =2 !u:@unit', {
  unit: '元',
  _unit_convert_out: { '元': { '分': 0.01 } }
})  // '100.00元'

// 使用 div 配置(米转千米)
calc('1000 | =2', {
  _unit_convert_out: { '千米': { '米': { div: 1000 } } },
  _unit_default_out: '千米',
  _unit_default_position: 'after'
})  // '1.00千米'

// 多组转换配置
calc('100 | =2 !ua:美元:美分', {
  _unit_convert_out: {
    '元': { '分': 0.01 },
    '美元': { '美分': 0.01 }
  }
})  // '1.00美元'

// 自定义转换函数
calc('100 | =2 !ub:USD', {
  _unit_convert_out: {
    'USD': { 'CNY': (value, input, output) => value / 7.2 }
  }
})  // 'USD13.88'
Ctrl+D 选择词, Ctrl+/ 注释

基于 MIT 许可发布