开发工具后端【免费下载链接】firebase-js-sdkFirebase Javascript SDK项目地址https://gitcode.com/gh_mirrors/fi/firebase-js-sdk点击查看免费下载导读Decimal128Value是 Firebase JS SDK 的 Firestore 模块中用于表示128 位十进制decimal128类型的封装类专为需要远超 JavaScript 原生number64 位双精度浮点、安全整数仅到 2^53-1精度的金融、科学计算等场景而设计。本指南以官方 API 参考文档 docs-devsite/firestore.decimal128value.md 为核心骨架结合仓库中 decimal128_value.ts 的实现与单元/集成测试完整讲解该类的构造、属性、比较语义、JSON 序列化以及它在文档读写、排序比较、字段变换中的底层行为。读完本文你将掌握如何在 Firestore 文档中正确写入、读取并比较 decimal128 字段。类概览Decimal128Value 是什么Decimal128Value代表 Firestore 文档中的 128 位十进制类型。它是一个公开的封装类将用户传入的十进制字符串解析为内部的 128 位Quadruple表示并对外暴露只读的stringValue属性、isEqual()相等比较方法和toJSON()序列化方法。export declare class Decimal128Value从 API 参考文档可见该类的公开成员包含成员类型说明constructor(value: string)构造器用十进制字符串构造一个新实例stringValue只读string构造时传入的十进制字符串isEqual(other)boolean判断两个Decimal128Value是否相等toJSON()object返回可 JSON 序列化的对象表示在 SDK 中该类的导出位于 packages/firestore/src/api.tsexport { Decimal128Value } from ./lite-api/decimal128_value;它与其他 Firestore 扩展类型如VectorValue、Int32Value、RegexValue、BsonObjectId、BsonTimestamp、MinKey、MaxKey并列导出共同构成 Firestore 对 BSON/扩展数值类型的支持。构造函数与字符串格式约束构造签名constructor(value: string);构造器接收一个十进制字符串将其保存在只读属性stringValue中同时调用内部工具类Quadruple.fromString(value)把字符串解析为 128 位二进制浮点表示constructor(value: string) { this.stringValue value; this.value Quadruple.fromString(value); }见 packages/firestore/src/lite-api/decimal128_value.ts合法字符串格式从 packages/firestore/src/util/quadruple.ts 的Quadruple.fromString实现可以确认支持以下格式不允许空白字符特殊值NaN、Infinity、Infinity、-Infinity符合正则[-]?[0-9]*(\.[0-9]*)?([eE][-]?[0-9])?的十进制数字串例如1.2e3、-2.5e-2、123.456、0、0.0指数部分最多 9 位数字超出会抛出Error(Exponent too large s)字符串不能为空否则抛出Error(Invalid number s)集成测试 packages/firestore/test/integration/api/type.test.ts 覆盖了多种合法输入包括科学计数法大小写e/E、正负指数、纯整数、小数、0.0与0以及高达 34 位有效数字的精确值decimalSciPositive: new Decimal128Value(1.2e3), decimalSciNegative: new Decimal128Value(-2.5e-2), decimalSciPositiveCapE: new Decimal128Value(1.2345E5), decimalIntPositive: new Decimal128Value(12345), decimalFloatPositive: new Decimal128Value(123.456), decimalZeroFloat: new Decimal128Value(0.0), decimalPrecisePositive: new Decimal128Value(0.1234567890123456789012345678901234), decimalLargePositive: new Decimal128Value(1234567890123456789012345678901234)非法输入会被拒绝非法字符串会在写入文档时被拒绝。测试 packages/firestore/test/integration/api/type.test.ts 验证了空字符串、含空白的1 23. 4以及非数字的abc都会触发包含Invalid number的错误消息。内部 128 位表示QuadrupleDecimal128Value内部把字符串解析为Quadruple对象——由符号位negative、带偏置的指数biasedExponent以及高 64 位、低 64 位尾数mantHi、mantLo四个bigint/布尔字段组成export class Quadruple { negative: boolean; biasedExponent: number; mantHi: bigint; mantLo: bigint; // ... }见 packages/firestore/src/util/quadruple.ts十进制到二进制的转换由QuadrupleBuilder.parseDecimal完成指数偏置为0x7FFF_FFFFEXPONENT_BIASInfinity/NaN使用指数0xFFFF_FFFFEXPONENT_OF_INFINITY详见 packages/firestore/src/util/quadruple_builder.ts。这意味着用户看到的字符串只是一个可读视图实际的精度、排序与相等性判断全部发生在 128 位二进制表示层面。只读属性 stringValuestringValue是构造时传入的原始字符串类型为string且被声明为readonlyreadonly stringValue: string;该属性同时承担两个角色面向用户的文本视图保留用户传入的原始写法例如1.2e3即使数值相同但写法不同的两个实例如1.0与1stringValue也各不相同。序列化与数据传输的载体SDK 在将值写入 Firestore 时会把stringValue放入保留键__decimal128__的 map 字段中见下文“写路径”。从源码结构可以推断stringValue是判断与序列化的核心依据而真正的数值比较则委托给内部的Quadruple。相等性比较 isEqual()方法签名与语义isEqual(other: Decimal128Value): boolean;返回true当且仅当本实例与传入的other相等。实现见 packages/firestore/src/lite-api/decimal128_value.tsisEqual(other: Decimal128Value): boolean { // Firestore considers 0 and -0 to be equal. if (this.value.isZero() other.value.isZero()) { return true; } return this.value.compareTo(other.value) 0; }关键语义0 与 -0 相等与 Firestore 全局的数值比较约定一致0、-0以及写法上的0、0.0、0、-0、0.0、-0.0彼此视为相等。单元测试 packages/firestore/test/unit/model/values.test.ts 将所有这些写法放入同一相等组验证// zeros all compare the same. [ { integerValue: 0 }, { doubleValue: 0 }, { doubleValue: -0 }, wrap(new Int32Value(0)), wrap(new Decimal128Value(0)), wrap(new Decimal128Value(0.0)), wrap(new Decimal128Value(-0)), wrap(new Decimal128Value(-0.0)), wrap(new Decimal128Value(0)), wrap(new Decimal128Value(0.0)) ]比较的底层实现Quadruple.compareTo按如下顺序逐位比较见 packages/firestore/src/util/quadruple.ts先处理 NaN所有 NaN 彼此相等且大于一切数值符号位负数小于正数带偏置指数高位尾数mantHi低位尾数mantLo。因此1与1.0这种写法不同但数值相同的实例经isEqual判断为相等见 values.test.ts 中的[wrap(new Decimal128Value(1)), wrap(new Decimal128Value(1.0))]相等组。JSON 序列化 toJSON()方法签名与输出格式toJSON(): object;返回“可 JSON 序列化的对象表示”。实现固定输出带__decimal128__标记的包装对象见 packages/firestore/src/lite-api/decimal128_value.tstoJSON(): object { return { __decimal128__: { stringValue: this.stringValue } }; }例如new Decimal128Value(-1.2e3).toJSON()的结果为{ __decimal128__: { stringValue: -1.2e3 } }这与 Firestore 内部 proto 表示、以及 canonicalId稳定排序/哈希 ID完全一致——单元测试 packages/firestore/test/unit/model/values.test.ts 断言expect(canonicalId(wrap(new Decimal128Value(-1.2e3)))).toBe( {__decimal128__:-1.2e3} );保留键__decimal128__在 packages/firestore/src/model/values.ts 中定义export const RESERVED_DECIMAL128_KEY __decimal128__;在 Firestore 文档中写入与读取 decimal128 字段写路径user_data_reader当用户把Decimal128Value实例放入setDoc/addDoc/updateDoc的数据对象时packages/firestore/src/lite-api/user_data_reader.ts 会识别该类型并调用parseDecimal128Value将其转换为 proto 值} else if (value instanceof Decimal128Value) { return parseDecimal128Value(value); }转换函数user_data_reader.ts把字符串塞进保留键 mapexport function parseDecimal128Value(value: Decimal128Value): ProtoValue { const mapValue: ProtoMapValue { fields: { [RESERVED_DECIMAL128_KEY]: { stringValue: value.stringValue } } }; return { mapValue }; }读路径user_data_writer读取时packages/firestore/src/lite-api/user_data_writer.ts 根据类型顺序判断出 decimal128 表示然后通过convertToDecimal128Value还原为Decimal128Value实例user_data_writer.tsprivate convertToDecimal128Value(mapValue: ProtoMapValue): Decimal128Value { const value mapValue!.fields?.[RESERVED_DECIMAL128_KEY]?.stringValue ?? ; return new Decimal128Value(value); }isDecimal128Value判定函数要求 map 中恰好只有一个字段且为__decimal128__且带非空stringValue见 packages/firestore/src/model/values.ts。完整读写示例集成测试 packages/firestore/test/lite/integration.test.ts 演示了完整的写入—读取—相等校验循环const ref await addDoc(coll, { objectId: new BsonObjectId(507f191e810c19729de860ea), int32: new Int32Value(1), decimal128: new Decimal128Value(1.2e3), min: MinKey.instance(), max: MaxKey.instance(), regex: new RegexValue(^foo, i) }); // ... const snap1 await getDoc(ref); expect(snap1.get(decimal128).isEqual(new Decimal128Value(1.2e3))).toBe(true);decimal128 字段既可以出现在文档顶层也可以嵌套在数组type.test.ts和对象内部type.test.ts使用。decimal128 在数值比较与排序中的角色与普通数字统一排序Firestore 的类型排序中decimal128 属于数值类别与integerValue、doubleValue、Int32Value一起参与数值排序。compareNumbers的实现packages/firestore/src/model/values.ts说明只要参与比较的任意一方是 decimal128双方都会被提升为 128 位 Quadruple 表示后比较// If either number is Decimal128, we cast both to wider (128-bit) representation, and compare those. if (isDecimal128Value(left) || isDecimal128Value(right)) { return compareQuadruples(left, right); }numberEquals也有类似逻辑values.ts。单元测试验证了这些语义-1、doubleValue -1、Int32Value(-1)、Decimal128Value(-1)、Decimal128Value(-1.0)全部按数值相等排序values.test.ts-2147483648、Int32Value(-2147483648)、Decimal128Value(-2147483648)、Decimal128Value(-2.147483648e9)数值相等values.test.tsNaN与Decimal128Value(NaN)视为同一排序档位values.test.ts。从测试还可以看出decimal128 能表达超出 JS 安全整数范围的值例如Number.MIN_SAFE_INTEGER - 1对应的Decimal128Value(-9007199254740992)values.test.ts这正是 128 位类型的核心价值所在。在排序规则中的位置单元测试同时确认在跨类型排序时Decimal128Value(1.2e3)与Int32Value(1)、普通 double、integer 按数值大小穿插排序values.test.ts 附近及排序区间断言说明 decimal128 不会破坏既有数值顺序。decimal128 与字段变换Field Transformincrement变换在操作数是 decimal128 时同样会保留 decimal128 语义。实现位于 packages/firestore/src/model/transform_operation.tsif (isDecimal128Value(baseValue) || isDecimal128Value(transform.operand)) { return { mapValue: { fields: { [RESERVED_DECIMAL128_KEY]: { stringValue: sum.toString() } } } }; }而当需要把 decimal128 当作普通数值参与运算时会通过parseFloat读取其字符串值transform_operation.ts。decimal128 与 Firestore 查询管道Pipelines在 Firestore Pipelines查询管道中decimal128是isType()支持的类型标签之一用于类型判别。文档注释见 packages/firestore/src/lite-api/expressions.ts* Supported values for type are: * null, array, boolean, bytes, timestamp, geo_point, number, * int32, int64, float64, decimal128, map, reference, string, * vector, max_key, min_key, object_id, regex, request_timestamp.管道测试 packages/firestore/test/lite/pipeline.test.ts 验证int64 字段被isType(field, decimal128)判定为falsefloat64 同样如此——即decimal128是一个独立的类型标签与int64、float64、number相互区分。实战建议与注意事项数值精度JS 原生number只有 53 位有效精度而 decimal128 提供 128 位约 34 位十进制有效数字。需要表示大整数超过 2^53或高精度小数时应优先使用Decimal128Value并始终以字符串形式构造。字符串即事实stringValue保留原始写法isEqual判断的是数值是否相等1与1.0相等0与-0相等而toJSON()输出的是原始字符串。格式校验构造器接受任何字符串但写入文档时才会触发底层Quadruple.fromString解析非法格式空串、含空白、非数字会在写入时报错消息形如Invalid number ...建议在构造前自行校验。管道类型判别在 Pipeline 中使用isType(field, decimal128)可精确判断字段是否为 decimal128注意它与number、int64、float64是不同的类型标签。排序兼容decimal128 与整数、浮点数按数值统一排序且支持NaN、Infinity等特殊值可用于数值混排场景。深入源码的索引API 参考文档docs-devsite/firestore.decimal128value.md类实现packages/firestore/src/lite-api/decimal128_value.ts128 位表示与字符串解析packages/firestore/src/util/quadruple.ts、packages/firestore/src/util/quadruple_builder.ts保留键与数值比较packages/firestore/src/model/values.ts读写转换packages/firestore/src/lite-api/user_data_reader.ts、packages/firestore/src/lite-api/user_data_writer.ts集成测试packages/firestore/test/integration/api/type.test.ts、packages/firestore/test/lite/integration.test.ts单元测试packages/firestore/test/unit/model/values.test.ts赞分享开发工具后端【免费下载链接】firebase-js-sdkFirebase Javascript SDK项目地址https://gitcode.com/gh_mirrors/fi/firebase-js-sdk点击查看免费下载相关推荐Firebase JS SDK 中 BsonObjectId 类完全解析Firestore BSON ObjectId 的读写、比较与排序原理Firebase JS SDK 中 BsonObjectId 类完全解析Firestore BSON ObjectId 的读写、比较与排序原理 本篇文章围绕开发工具后端Firebase JavaScript SDK Firestore Bytes 类完全指南不可变字节数组的构造、序列化与相等性比较Firebase JavaScript SDK Firestore Bytes 类完全指南不可变字节数组的构造、序列化与相等性比较 Bytes 是 Fireb开发工具后端Firebase JS SDK 中 AuthCredential 类完全指南凭据模型、序列化与登录实战Firebase JS SDK 中 AuthCredential 类完全指南凭据模型、序列化与登录实战 AuthCredential 是 Firebase A开发工具后端上一篇如何快速上手Qwen3-0.6B-Base对话测试与性能评估实战教程下一篇QuickRecorder macOS 屏幕录制指南双音轨、窗口录制与演讲者前置实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考