Skip to content

扩展维度

LunarUnits 把 SI 基本量纲作为稳定核心,同时允许角度、计数、货币、信息量等概念以扩展维度进入同一套单位系统。这个设计的目标不是扩大 SI 本身,而是在应用层保留足够的工程语义。

数学视角

由前文我们知道,SI 基本量纲为由若干基向量生成的自由系统提供了默认的正交基。扩展维度则是在不改变 SI 基础定义的前提下,加入新的独立基向量。

text
SI basis       = {L, M, T, I, Theta, N, J}
extended basis = SI basis + {Angle, Count, Money, Information}

在这个视角下,length / timemoney / countcount / time 都只是不同基向量上的整数线性组合。关键问题不再是“这些概念能不能被数学地压成标量”,而是“在工程计算中是否应该保留它们的独立语义”。LunarUnits 对扩展维度的选择就是在这两者之间偏向保留语义。

SI 与扩展维度分包

核心包提供通用的 DimensionUnitQuantity 运算结构,SI 相关定义集中在 dimensions/siunits/siquantities/si 等包中。长度、质量、时间、电流、温度、物质的量和发光强度构成默认的物理计算基础。

扩展维度使用平行的分包组织,例如 angle、information、currency、count 等领域各自提供 dimension、unit 和 quantity 入口。它们复用核心运算模型,但不会反向进入 SI 核心包。这样做有几个实际收益:

  • SI 基础保持清晰,用户只需要基础物理单位时不会被业务维度干扰。
  • 扩展领域可以按需引入,货币、信息量、计数等定义不会成为所有使用者的默认负担。
  • Catalog 可以在应用边界组合 SI 与扩展单位,解析和格式化层不需要知道每个领域的内部实现。
  • 新扩展维度可以沿用相同包形态加入,而不需要改动核心模型。

因此,扩展维度不是对 SI 的修补,而是 LunarUnits 在包结构上为非 SI 语义保留的独立入口。

角度的显式建模

角度最容易被误认为“就是无量纲”。数学上弧度常被视为长度比值,但工程计算中如果把角度完全压成 ordinary dimensionless,就会混淆几类不同概念:纯比例、平面角、周期频率和角频率。

LunarUnits 选择把 angle 建模为扩展维度。度、弧度和整圈仍然可以互相换算,1 Hz = 2*pi rad/s 这样的关系也可以通过单位换算表达;但 rad/s 不会退化成普通 1/s,纯比例也不会被误认为角度。

这个选择还影响力矩与能量的建模:能量可以看作力矩乘以角度,因此力矩和能量在 LunarUnits 中不会因为角度被抹平而具有相同量纲。对于面向工程输入、公式计算和格式化输出的库来说,保留这层语义比过早消去它更有价值。

代价是它不完全等同于某些教材里的 “radian is dimensionless” 约定。这个差异是刻意的,目的是让用户输入和 API 输出更明确。

计数的显式建模

计数也没有被建模成普通无量纲。3 items12 bottles40 requests 这些值在数学上可以看成标量,但在应用里通常代表离散对象或事件数量。把它们直接压成 scalar,会让单价、吞吐量、错误率和普通比例之间的边界变得含糊。

显式 count 维度让这些关系可以被单位系统表达:

  • 金额除以计数得到 unit price,例如 money/count。
  • 计数除以时间得到 throughput,例如 count/time。
  • 单价乘以计数会消去 count 并恢复为金额。
  • 纯缩放系数仍然留在 dimensionless,不和业务数量混在一起。

count 也不同于 SI 中的 amount of substance。物质的量描述微观实体规模并使用 mole 作为单位;count 面向应用对象、事件和业务实体。两者都可以参与单位运算,但语义来源不同,所以放在不同的维度入口中。

边界

扩展维度解决的是“这些量是否应在单位系统中保留独立语义”的问题,不替代领域模型本身。货币汇率仍然需要调用方在边界注入,商品种类、请求类型、业务含义仍然需要由应用代码表达。LunarUnits 负责保证单位组合、换算和量纲检查一致。