更新记录

1.1.0(2026-09-20)

新增鸿蒙(HarmonyOS / app-harmony)端支持。

  • 鸿蒙端用纯 UTS(编译到 ArkTS)实现,不带原生库、不需要额外配置, 17 个 API 与 Android / iOS / H5 同签名。
  • 错误类型同样是三种(非法数字 / 除零 / 非法参数);鸿蒙端与 H5 端一样抛普通 Error、 靠 message 判别,message 文案与 H5 端逐字一致(App-Android / iOS 仍是原生类型化异常)。

验证到哪一层(如实写)

  • 以我们已上线的原生计算核心为真值源,导出 69019 条随机 + 边界用例(含 7 种舍入在 .5 撞点、 96-bit 溢出边界、复利指数跨档),鸿蒙端逐条比对值与错误类型:68870 条逐字相同。
  • 其余 149 条只出现在 compoundInterest 且 期数 × 年数 ≥ 1024 时,差异是第 29 位有效数字差 1 (≤1 个末位单位)。用 Python 高精度算术(prec=120)逐条裁决:149/149 是本插件更接近真值。 按 2 位小数取整后无一条不同。我们不写「完全一致」,如实写「≤1 个末位单位」。
  • 已通过鸿蒙目标的真实编译:转译成 ArkTS → 生成鸿蒙工程 → 依赖安装 → 打出 .hap 运行包。

1.0.0(2026-07-19)

首发:自研高性能原生金融级任意精度十进制核心,提供 uni-app 可调的 JS API。


平台兼容性

uni-app(5.14)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× √ √ √ √ - 5.0 12 √
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × - × ×

uni-app x(5.14)

Chrome Safari Android iOS 鸿蒙 微信小程序
√ √ 5.0 12 √ ×

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × × √

nex-decimal —— 金融级任意精度十进制计算

自研高性能原生金融精算核心,提供 uni-app 可调的 JS API。 支持 App 端(Android / iOS) 与 H5 端(17 个 API 全量可用; H5 端建议应用启动时 await ensureReady() 一次);小程序不支持。 鸿蒙(HarmonyOS)端实现已就绪但尚未标记支持,原因与当前可用程度见下方 鸿蒙(HarmonyOS)端现状。

同一份 utssdk 插件同时支持 uni-app x(uvue) 与 经典 uni-app(vue3),无需分叉。 全程 string 进 string 出:金额/数字用十进制字符串承载,避免 f64 精度丢失—— 0.1 + 0.2 在 JS(IEEE-754 f64)下等于 0.30000000000000004,本插件 decAdd("0.1","0.2") 精确返回 "0.3"。 自研核心,无额外系统依赖。适用:电商金额、账单、利息、汇率、报表合计等不容精度误差的场景。

为什么需要它

JavaScript 的 number 是双精度浮点,做金额运算会丢精度(0.1+0.2、0.3-0.1、1.1*3 都不准), 四舍五入、银行家舍入、千分位格式化也要自己拼。本插件把这些交给原生定点十进制核心,精确、可控、一致。

API(17 个)

组 JS API 签名 说明
算术 decAdd decAdd(a, b): string a + b(去尾随零)
decSub decSub(a, b): string a - b
decMul decMul(a, b): string a × b
decDiv decDiv(a, b, scale?, rounding?): string a ÷ b,默认 scale=28、rounding="HalfUp";除零抛错
decCompare decCompare(a, b): number a<b→-1 / 相等→0 / a>b→1("2.50"=="2.5")
舍入/符号 decRound decRound(a, scale, rounding): string 舍入到 scale 位,精确保留 scale(补零)
decAbs decAbs(a): string 绝对值
decNeg decNeg(a): string 取负
聚合 decSum decSum(values): string 求和(空数组抛参数错误)
decAvg decAvg(values, scale?, rounding?): string 平均=和/个数
decMax decMax(values): string 最大值
decMin decMin(values): string 最小值
格式化/利息 decFormat decFormat(a, scale, thousandsSep, currencySymbol): string 货币格式化(千分位 + 货币符号)
compoundInterest compoundInterest(principal, annualRate, periodsPerYear, years): string 复利终值(本息合计)
simpleInterest simpleInterest(principal, annualRate, years): string 单利终值(本息合计)
表达式 decEval decEval(expr): string 求值算术表达式串,全程 Decimal(去尾随零)
decEvalScale decEvalScale(expr, scale, rounding): string 求值后舍入到 scale(精确补零)

scale/periodsPerYear/years 传 number(整数);thousandsSep 传 boolean;values 传 string[]。

舍入策略(rounding 参数)

"HalfUp"(四舍五入,远离零)| "HalfEven"(银行家,就近偶数)| "HalfDown"(中点趋零)| "Up"(远离零)| "Down"(趋零截断)| "Ceiling"(向正无穷)| "Floor"(向负无穷)。非法名抛参数错误。

经典对照:decRound("2.5",0,"HalfUp")=="3",decRound("2.5",0,"HalfEven")=="2"。

用法

import {
  decAdd, decDiv, decRound, decSum, decFormat, compoundInterest
} from '@/uni_modules/nex-decimal';

// 浮点陷阱终结者
decAdd('0.1', '0.2');            // "0.3"(JS: 0.1+0.2 = 0.30000000000000004)
decSum(['19.99', '0.01', '5']);  // "25"

// 除法:4 位小数、四舍五入
decDiv('1', '3', 4, 'HalfUp');   // "0.3333"

// 舍入(精确保留 scale,补零)
decRound('1.5', 2, 'HalfUp');    // "1.50"

// 货币格式化
decFormat('1234.5', 2, true, '¥');   // "¥1,234.50"
decFormat('-1234567.891', 2, true, '$'); // "-$1,234,567.89"

// 复利:本金 1000、年利率 5%、按月复利、1 年
const amount = compoundInterest('1000', '0.05', 12, 1); // ≈ 1051.16189...
decRound(amount, 2, 'HalfUp');   // "1051.16"

// 表达式引擎:把整条算式当字符串求值,全程 Decimal(非 f64)
decEval('0.1+0.2');              // "0.3"
decEval('1+2*3');               // "7"(优先级)
decEval('(1+2)*3');             // "9"
decEval('2^10');                // "1024"(幂,整数指数)
decEval('1.1*(2+3.5)/7');       // 全精度小数
decEval('abs(-5)');             // "5";也支持 sqrt(x)/round(x,n)
decEvalScale('10/3', 2, 'HalfUp'); // "3.33"(求值后舍入到 2 位)

🔴 App 端调用 decDiv / decAvg 时,scale 与 rounding 必须显式传值—— 别写成 decDiv('1', '3')。

签名里的 scale? / rounding? 是 UTS 的可空标记,不是「有默认值、可省略」的意思: 它编到 Kotlin / Swift 不会生成默认值参数,省略即编译报错 No value passed for parameter 'scale'。 只有 H5 / 小程序(走 TS 语义)可以省。 想要「默认 28 位、四舍五入」就把它写出来:decDiv('1', '3', 28, 'HalfUp')。

实测:2026-09-20 走 UTS 编译器(app-android 转译通道)专门编了一轮省参调用, 4 条报错全部落在调用处、插件源码零错。app-harmony 目标的真编译尚未跑通(见下方鸿蒙端小节), 同机制推断一致但未实证;H5 端可省是 TS 语义,确定。

错误处理

可失败函数在原生层抛异常(Android DecException / iOS DecError),UTS 侧透传,用 try/catch 捕获:

try {
  decDiv('1', '0', 28, 'HalfUp');   // 抛 DivideByZero(可选参 App 端必须显式传,见上)
} catch (e) {
  console.error(e);
}
  • 非法数字串(空串 / 非数字 / 溢出)→ InvalidNumber。
  • 除数为零 → DivideByZero。
  • 舍入模式名非法 / scale 超 28 / 聚合空数组 / periodsPerYear=0 → InvalidParam。
  • 表达式语法错误(括号不匹配 / 尾随运算符 / 空表达式 / 未知函数 / 非整数指数 / 嵌套过深)→ InvalidParam;表达式含非法字符或无法解析的数字 → InvalidNumber;表达式里除零 → DivideByZero。

边界 / 限制

  • Decimal 量程约 ±7.9×10²⁸、最多 28 位小数;超出即溢出 → InvalidNumber(不会 panic / 闪退)。
  • 利息函数返回全精度结果(复利可达多位小数),按需用 decRound / decFormat 收口到展示精度。
  • simpleInterest / compoundInterest 返回的是本息合计(最终金额),不是单纯利息。
  • App 端(Android / iOS)+ H5 端可用;小程序不支持;鸿蒙见下节。

鸿蒙(HarmonyOS)端现状

兼容性表格里 app-harmony 已是「支持」。 下面是它验到了哪一层、哪一层没验,不藏着:

  • 实现已就绪:utssdk/app-harmony/index.uts,纯 UTS(编译到 ArkTS), 不带原生库、不需要额外配置,17 个 API 全量对齐(与其它端同签名、同错误类型)。

  • 已验到哪一层(逐条可复现,命令见仓库 scripts/harmony-diff/):

    层级 内容 结果
    算术等价 以我们已上线的原生计算核心为真值源,导出 69019 条随机 + 边界向量,逐条比对值与错误类型 68870 条逐字相同;149 条见下
    判据有效性 改坏 5 处承重分支(舍入半分点 / 解析进位 / 精度上限 / 宽路工作精度 / 压位) 5/5 当场报红、还原复绿
    声明↔实现 机械门核对齐备性 17/17
    源码合法性 真 UTS 编译器转译(经 Android 通道,同一份源码靠软链保证不漂) 通过
    鸿蒙目标真编译 cli launch app-harmony --compile:转译 → 生成鸿蒙工程 → 装 ohpm 依赖 → 打包 通过,产物见下
    鸿蒙真机 / 模拟器实跑 — 未做(手上没有鸿蒙设备)
  • 已知偏差(唯一一处):compoundInterest 在 periodsPerYear × years ≥ 1024 时, 与我们其它端的原生核心相差 ≤1 个末位单位(第 29 位有效数字)。 根因是原生核心在超大指数时走的一条高位中间量快路自带约 1 个末位单位误差; 用 Python 高精度算术(prec=120)对 149 条逐条裁决,149/149 是鸿蒙端更接近真值。 按 2 位小数取整后无一条不同。我们不写「完全一致」,如实写「≤1 个末位单位」。

  • 鸿蒙目标编译的产物(2026-09-20,HBuilderX 5.23 + DevEco Studio 6.1.1.300 实测):

    • utssdk/app-harmony/index.uts → 转译出 ArkTS index.ets, 17 个 API 逐名导出、与 interface.uts 声明零差集,错误文案原样带过去;
    • 自动生成鸿蒙工程、ohpm 依赖安装成功、打出 .hap 运行包(15MB / 55 个文件)。
    • 该包未签名(本机没配数字证书)——签名只影响装机,不影响编译结论。
  • 🔴 仍然没做的那一层,请务必看清楚:没有在鸿蒙真机或模拟器上跑过。 上面所有结论都是「算得对(差分)」+「编得出来(真编译 + 出包)」, 不含「装到设备上跑起来行为正确」。要上生产请自行在目标设备上回归一轮。

  • 为什么还不标「支持」:上面全部验证都在电脑上完成——算术靠差分、源码靠编译器。 没有任何鸿蒙真机数据,且鸿蒙目标的真编译本机尚未跑通。 兼容性表格是对外承诺,拿不出真机证据就不翻。

鸿蒙是您的硬需求?联系我们排真机验证;您手上有鸿蒙设备的话可以先拿内测版本跑。

质量与验证

  • 所有运算溢出安全:溢出返回可捕获错误、绝不闪退;表达式引擎带深度守卫,深嵌套报错而非栈溢出。
  • 50 项自动化测试全量通过(含 0.1+0.2、银行家舍入、复利手算锚、除零,及表达式优先级/幂/函数/语法错误/深嵌套等金标)。
  • App 端为原生插件,需自定义基座或云打包运行。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。