
金融科技【免费下载链接】dinero.jsCreate, calculate, and format money in JavaScript and TypeScript项目地址https://gitcode.com/gh_mirrors/di/dinero.js点击查看免费下载加密货币Bitcoin、Ethereum 等在 dinero.js 中与普通法币并无本质区别——只要币种对象满足DineroCurrency类型约束就可以直接用于创建、计算和格式化金额。但由于加密货币普遍拥有极高的细分位数如 ETH 可细分到 18 位小数默认的number金额类型很快会触及 IEEE 754 的精度上限因此本指南将围绕如何为加密货币定义合规币种、选用bigint变体或第三方任意精度库以及避开文件命名陷阱展开读完即可在自己的项目中安全落地加密货币金额处理。加密货币也是普通货币一切从DineroCurrency说起Dinero.js 之所以能像处理任何其他货币一样处理加密货币根源在于它对货币的定义非常收敛一个货币在库中就是一个实现了DineroCurrency类型的普通对象。该类型定义于 packages/dinero.js/src/currencies/types/DineroCurrency.tsexport type DineroCurrencyTAmount, TCurrency extends string string { /** * The unique code of the currency. */ readonly code: TCurrency; /** * The base, or radix of the currency. */ readonly base: TAmount | readonly TAmount[]; /** * The exponent of the currency. */ readonly exponent: TAmount; };它只包含三个字段字段类型含义codeTCurrency默认string货币的唯一代码如ETH、BTCbaseTAmount或TAmount[]货币的基数进制通常为10数组形式用于非十进制货币exponentTAmount指数即该货币最多可细分的小数位数只要某个加密货币对象满足这三个字段它就可以被传入dinero({ amount, currency })并参与add、multiply、allocate、toDecimal等全部 API 的运算。换句话说加密货币在 dinero.js 中不需要任何特殊代码路径唯一要做的就是把币种喂给类型系统。以 Ethereum 为例一个最朴素的币种定义是const ETH { code: ETH, base: 10, exponent: 18, }; const price dinero({ amount: 1000000000000000000, currency: ETH });这正是官方文档 Precision and large numbers 中给出的写法——但它同时也是反面教材因为以number表示的1000000000000000000已经超过了 JavaScript 数字的安全整数范围。原因见下一节。为什么加密货币必须搭配 bigint 或任意精度库加密货币普遍拥有高指数1 ETH 在链上可细分到 18 位小数即 1 ETH 10^18wei最小单位。dinero.js 要求金额以最小货币单位minor currency units传入也就是说表示 1 ETH 需要整数1000000000000000000。而 JavaScript 的number类型基于 IEEE 754 双精度浮点只能精确表示-(2^53 - 1)到2^53 - 1范围内的整数即约 9007 万亿。一旦金额超出这个范围二进制转换时就会被截断产生精度损失。文档 docs/guides/precision-and-large-numbers.md 明确给出了这条警示import { dinero } from dinero.js; const ETH { code: ETH, base: 10, exponent: 18, }; // Dont do this! // 1000000000000000000 is too big for accurate representation // in IEEE 754 numbers. const price dinero({ amount: 1000000000000000000, currency: ETH });因此官方指南给出的结论是处理加密货币时应使用bigint原生类型或使用 big.js 这类第三方任意精度库见 docs/guides/cryptocurrencies.md。在金额类型的选择上核心权衡是精度 vs 性能number性能极佳硬件实现但可精确表示的范围有限适合金额可控的电商、定价页等场景bigint支持任意精度整数比任何用户态任意精度库都快但显著慢于number软件实现且无法直接 polyfill、难以高效转译到 ES5也没有原生的JSON.stringify/JSON.parse支持第三方库如 big.js、JSBI浏览器与 Node.js 支持范围最广、可转译可 polyfill但运行逻辑与算法复杂度更高、包体积更大性能是三者中最差的。加密货币或股票交易这类金额可能突破number上限的应用官方建议直接采用bigint。其中bigint还隐含一层更深的优势它确保了所有整数运算的精确性不会出现浮点尾差。用 bigint 变体处理加密货币dinero.js/bigint与dinero.js/bigint/currenciesDinero.js 为 bigint 提供了开箱即用的完整工具链通过dinero.js/bigint子路径引入dinero及全部运算函数通过dinero.js/bigint/currencies引入 bigint 版本的币种定义。在源码层面bigint 变体只是把库内预置的 bigint calculator 注入createDinero工厂// packages/dinero.js/src/bigint/dinero.ts export const dinero createDinero({ calculator, });而 bigint 版币种定义 中的base与exponent一律是 bigint 字面量export const AED: DineroCurrencybigint { code: AED, base: 10n, exponent: 2n, };这带来一个必须牢记的约束参见 FAQ为什么不能用 bigint 搭配普通币种dinero.js/currencies下的币种如USD其base/exponent是number不能与dinero.js/bigint混用。因为 bigint 变体的所有运算都走 bigint 数学而 JavaScript 语言本身禁止number与bigint混算——10n 2会直接抛出TypeError: cant convert BigInt to number。所以只要使用 bigint 变体就必须从dinero.js/bigint/currencies导入币种。正确的加密货币ETH写法是import { dinero, add } from dinero.js/bigint; const ETH { code: ETH, base: 10n, exponent: 18n, }; // 1 ETH 10^18 wei以最小单位传入 const d1 dinero({ amount: 1000000000000000000n, currency: ETH }); const d2 dinero({ amount: 500000000000000000n, currency: ETH }); add(d1, d2); // 一个 amount 为 1500000000000000000n 的 Dinero 对象如果你手头已有number版的币种对象、又希望快速迁移到 bigint仓库测试工具 test/utils/castToBigintCurrency.ts 展示了一种优雅的转换思路——用BigInt逐字段转换base含数组分支与exponentexport function castToBigintCurrencyTCurrency extends string( currency: DineroCurrencynumber, TCurrency ): DineroCurrencybigint, TCurrency { return { ...currency, base: Array.isArray(currency.base) ? currency.base.map(BigInt) : BigInt(currency.base as number), exponent: BigInt(currency.exponent), }; }更进一步用自定义 calculator 接入第三方任意精度库如果目标运行环境不支持bigint例如需要兼容老浏览器官方给出的替代路线是自行实现一个 calculator把 big.js 之类的第三方库接入 dinero.js。这里的原理很直接dinero.js 把所有计算都委托给类型特定的 calculator 对象——calculator 完全决定了你可以向 Dinero 对象传入什么金额类型见 docs/guides/precision-and-large-numbers.md 与 packages/dinero.js/src/core/helpers/createDinero.ts。calculator 需要实现DineroCalculator接口packages/dinero.js/src/core/types/DineroCalculator.tsexport type DineroCalculatorTInput { readonly add: DineroBinaryOperationTInput; readonly compare: DineroBinaryOperationTInput, DineroComparisonOperator; readonly decrement: DineroUnaryOperationTInput; readonly integerDivide: DineroBinaryOperationTInput; readonly increment: DineroUnaryOperationTInput; readonly modulo: DineroBinaryOperationTInput; readonly multiply: DineroBinaryOperationTInput; readonly power: DineroBinaryOperationTInput; readonly subtract: DineroBinaryOperationTInput; readonly zero: () TInput; };共 9 个二元/一元操作加一个zero()其中compare返回DineroComparisonOperatorLT -1、EQ 0、GT 1。用 big.js 实现它非常直观因为每个方法几乎都是一行映射import Big from big.js; import { DineroCalculator, DineroComparisonOperator } from dinero.js; const calculator: DineroCalculatorBig { add: (a, b) a.plus(b), compare: (a, b) a.cmp(b) as unknown as DineroComparisonOperator, decrement: (v) v.minus(new Big(1)), increment: (v) v.plus(new Big(1)), integerDivide: (a, b) a.div(b).round(0, Big.roundDown), modulo: (a, b) a.mod(b), multiply: (a, b) a.times(b), power: (a, b) a.pow(Number(b)), subtract: (a, b) a.minus(b), zero: () new Big(0), };拿到 calculator 后通过createDinero工厂生成自定义的dinero函数import { createDinero } from dinero.js; // ...calculator 定义见上... const bigDinero createDinero({ calculator });在 createDinero 的实现 中可以看到工厂默认的 formatter 是{ toNumber: Number, toString: String }。对高精度金额而言String会把大数输出成科学计数法如1e22而非完整数字这会让toDecimal等格式化功能出错。因此使用自定义金额类型时必须同时提供自定义 formatter实现DineroFormatter接口packages/dinero.js/src/core/types/DineroFormatter.tsimport Big from big.js; import { DineroFormatter } from dinero.js; const formatter: DineroFormatterBig { toNumber: (value) value.toNumber(), toString: (value) value.toFixed(), };随后把 formatter 与 calculator 一起注入const bigDinero createDinero({ calculator, formatter });这样接入第三方库后的bigDinero({ amount: new Big(1000000000000000000), currency: ETH })就能既保持任意精度运算又输出完整十进制字符串。官方也提醒虽然传入整个 calculator 意味着可能携带用不到的方法但这几乎不构成瓶颈——因为 big.js 场景下这些方法本来就存在于每个Big对象上同时dinero.js 不背书任何特定任意精度库接入前需要自行验证其行为符合预期。为什么官方不提供加密货币的现成实现一个常见疑问是dinero.js/currencies里有完整的 ISO 4217 法币列表packages/dinero.js/src/currencies/iso4217.ts为什么没有 BTC、ETH官方在 docs/guides/cryptocurrencies.md 中给出了明确理由加密货币的币种定义非规范性且不稳定non-normative and unstable。法币的 ISO 4217 标准由权威机构维护、变更缓慢而加密货币的代码、进制、细分位数可能随分叉、升级而变动维护这样一份列表的成本过高。因此更合理的分工是把它们留在用户态userland——由使用方按需定义正如本指南前文所示自定义一个加密货币只需实现三字段的DineroCurrency类型即可。从类型设计上看DineroCurrencyTCurrency extends string string中的泛型参数TCurrency还带来了货币级类型安全仓库的 currency-safety 类型测试 验证了add(dineroUSD, dineroEUR)这类跨币种操作会在编译期直接报错而allocate、multiply、trimScale等一元操作会保留原币种类型。为加密货币定义字面量 code如ETH时同样能享受到这一层防护避免把 ETH 与 USD 金额误加在一起。文件命名警告避开广告拦截器的误伤最后是一条实战中极易踩坑的警告同样来自 docs/guides/cryptocurrencies.md小心你的文件命名。加密货币挖矿脚本常使用对应币种的非官方 ISO 4217 代码来命名文件例如xbt.js对应 BTC或xmr.js对应 Monero。广告拦截器会按文件名屏蔽这类脚本导致它们加载失败。如果你的代码不经过打包bundle尤其要避免使用这类可疑文件名否则用户开启广告拦截器后你的脚本可能无法执行。这条警告对将加密货币逻辑放在独立模块中的项目尤其重要给存放币种定义的文件取名时尽量使用语义化且不易被误判的名称而不是直接照搬币种代码。小结处理加密货币金额时dinero.js 的方案非常克制而完整币种即数据——任何实现DineroCurrencycode/base/exponent的对象都可直接使用官方不为不稳定的加密货币维护内置列表由用户在 userland 自定义精度优先选 bigint——加密货币高指数易突破number安全范围推荐通过dinero.js/bigint与dinero.js/bigint/currencies使用且严禁与number版币种混用需要兼容老环境时写 calculator——实现DineroCalculator接口即可接入 big.js 等任意精度库同时配套自定义DineroFormatter保证toDecimal等格式化输出正确命名要谨慎——避免使用挖矿脚本惯用的非官方币种代码文件名防止广告拦截器误伤。相关扩展阅读Precision and large numbers金额类型选型全解、Why cant I use currencies with bigintbigint 混用报错原理、DineroCurrency 类型定义、bigint 变体工厂。赞分享金融科技【免费下载链接】dinero.jsCreate, calculate, and format money in JavaScript and TypeScript项目地址https://gitcode.com/gh_mirrors/di/dinero.js点击查看免费下载相关推荐基于 TensorFlow Lite Task Library 的 iOS 实时图像分类Image Classification 示例应用完全指南基于 TensorFlow Lite Task Library 的 iOS 实时图像分类Image Classification 示例应用完全指南 本文以 l金融科技Hikyuu Quant Framework夏普比率计算实现Hikyuu Quant Framework夏普比率计算实现 概述 夏普比率Sharpe Ratio是衡量投资组合风险调整后收益的重要指标由诺贝尔经济学金融科技dinero.js 自定义货币类型安全实践用 as const satisfies 获得编译期货币码校验dinero.js 自定义货币类型安全实践用 as const satisfies 获得编译期货币码校验 在 dinero.js 中定义自定义货币加密货币、金融科技上一篇终极指南揭秘spicetify-cli彩色终端输出的7个核心技术实现原理下一篇基于 Syne Tune 的异步随机搜索用多 worker 并行加速超参数优化D2L 实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考