目录

🌕 MoonMoney

专为 MoonBit 设计的轻量级、零依赖、高精度财务金额计算引擎。

MoonBit License Build Status


MoonMoney 是一个极其严谨的金额处理库。在商业交易系统(如电商、支付、金融结算)中,直接使用普通的浮点数处理金钱极易引发精度灾难(比如 0.1 + 0.2 = 0.30000000000000004)。 本项目基于 Int64 打造了绝对无损的核心引擎,并在编译器层面严格隔离不同币种的运算,确保您的业务代码永远不会因为类型错误或精度丢失而造成资金损失!

⚠️ 专项说明:为什么不直接使用通用库(如 DzmingLi/decimal)?

在 MoonBit 生态中,虽然已有 DzmingLi/decimal 等优秀的通用任意精度数学库,但这与 MoonMoney 的工程定位有着本质的区别:

  1. 领域专用 (Domain-Specific) vs 通用数学 (Generic Math)
    • decimal 解决的是纯粹的数值高精度运算问题。
    • MoonMoney 解决的是复杂的金融业务问题。它封装了“数值 + 币种 (Value + Currency)”,完美落地了 Java JSR-354 的 Money Pattern 架构。
  2. 严格的币种安全隔离 (Currency Type-Safety)
    • 使用 decimal 时,开发者极易在业务代码中无意间将 100 美元100 人民币 对应的对象相加,数学库会合法地返回 200,从而引发致命的金融故障。
    • MoonMoney 强制要求所有四则运算执行同源币种校验。一旦检测到美元与人民币直接相加,将立刻触发引擎级的 Abort 安全熔断,从根本上防止业务越界。
  3. 解决金融特有的“一分钱分配”问题 (The Penny Problem)
    • 使用 decimal 把 100 元平分给 3 个人,普通的精确除法结果是 33.333333...。在真实的支付结算中,如果直接截断或四舍五入会导致总账不平(33.33 * 3 = 99.99,凭空丢失了 0.01 元)。
    • MoonMoney 提供杀手级特性 allocate 智能无损分配算法。它通过精密轮询补偿,确保 100 元能被完美拆分为 [33.34, 33.33, 33.33]绝对保证资金守恒,一分钱不丢,这是纯算术库无法替代的核心金融特性。
  4. Wasm 极速内存模型 (Memory Footprint)
    • decimal 库为了支持超大精度的浮点数,底层涉及复杂的对象包装与精度上下文计算。
    • MoonMoney 专为高并发交易网关设计,直接采用极简的 Int64 存储资金的最小单元,完美避开浮点误差,同时在 Wasm 运行时的内存开销和计算延迟降到了最低。

✨ 核心特性

  • 彻底杜绝精度误差: 底层全部使用 Int64 存储分、厘等最小货币单位,切断浮点运算误差。
  • 跨币种安全隔离: 编译器级别防止错误地将“美元”和“人民币”直接相加,触发跨币种运算时提供极速拦截。
  • 智能无损分配算法 (Smart Allocation): 本项目最具价值的亮点。能够将一笔钱按任意比例完美拆分,绝不会丢失一分钱的除法余数。
  • 纯血 MoonBit: 0 外部依赖,完美实现了 Eq, Compare, Show 等原生 Traits,开箱即用。

🏛️ 核心架构

MoonMoney 的运算链路经过了严格的安全设计,其底层处理逻辑如下:

graph TD
    A[外部金额输入] --> B{是否存在精度风险?}
    B -- 是 (浮点数) --> C[拒绝接收 / 要求转为整型]
    B -- 否 (整型 Int64) --> D[绑定币种 Currency]
    D --> E[生成 Money 实例]
    E --> F{执行四则运算}
    F -- 跨币种操作 --> G[触发 Abort / 安全拦截]
    F -- 同币种操作 --> H[底层 Int64 高性能计算]
    H --> I[生成全新 Money 实例]
    
    E --> J{执行资金分配}
    J --> K[调用 allocate 算法]
    K --> L[整数比例切分]
    L --> M[余数轮询精密补偿]
    M --> N[输出完美的 Money 数组]

📦 极速安装

在您的 MoonBit 项目中,通过标准的 moon 包管理器安装:

moon add zfmLink/moon-money

🚀 最佳实践与场景演示

1. 基础金额创建

在电商系统中,我们通常用最小单位(如美分)来初始化商品价格。

// 创建一笔 10 美金的金额 (1000 美分)
let price = Money::new(1000L, usd) 
// 创建一笔 1.5 美金的税费
let tax = Money::new(150L, usd)    

2. 绝对安全的财务数学运算

MoonMoney 保证您不会在无意间犯下致命的财务逻辑错误。

let total = price.add(tax)
println(total) // 输出: "USD 1150"

// ❌ 灾难拦截:尝试将美元和人民币相加会直接 abort
// let invalid = price.add(Money::new(100L, cny)) 

3. 【杀手级功能】智能无损分配算法

假设有 100 块钱,需要平分给 3 个合伙人。如果直接除以 3,每人得 33.33,加起来是 99.99,那丢失的 1 分钱去哪了?在财务审计中这是绝对不被允许的。 调用我们的 allocate 算法即可完美解决:

let fund = Money::new(100L, cny) // 100 分钱
let shares = fund.allocate([1, 1, 1]) // 1:1:1 比例平分

// 算法会自动将余下的 1 分钱补给前列,一分不差!
println(shares[0]) // CNY 34
println(shares[1]) // CNY 33
println(shares[2]) // CNY 33

🤝 参与贡献

我们非常欢迎任何对高精度计算感兴趣的 MoonBit 开发者提交 PR 和 Issues。请阅读 CONTRIBUTING.md 了解更多关于本地开发和测试的信息。

📝 许可协议

本项目基于 MIT License 开源,您可以自由地将其应用于任何商业场景。

关于

MoonMoney 是一个原生、轻量且无依赖的 MoonBit 高精度财务与货币计算引擎。在商业系统中,使用常规浮点数计算金额极易引发精度丢失灾难(如 0.1 + 0.2 = 0.30000000000000004)。本项目参考了业界成熟的 Money Pattern,通过 64 位整型(Int64)封装和严格的 ISO-4217 货币类型校验,实现了 100% 精确的金额加减乘除与“无损智能分配

98.0 KB
邀请码