立即处理可能影响正在运行的系统原始 payload 不含 superseded_by 标记,但内嵌的连续 diff 明确显示一次 GetNumericVariantFromJson 回归修复以及多项累积转换修复。commit aa165fe9 及其 merge 未把 mormot.commit-num.inc 递增到 16851 以上,因此完整 landing SHA 很重要。
十进制解析在修复零值回归后实现精确 IEEE 舍入
本期继续稳定数值双向转换,并修复会影响生产结果的正确性问题。DoubleToAscii 现可正确处理科学计数法与 64-bit sticky bit 舍入,GetExtended 则接受边界 exponent,并把常见十进制小数舍入到最近的 IEEE double。GetNumericVariantFromJson 也恢复了对 0.0 的数值处理,因此交换 JSON number 或以文本持久化浮点值的 backend 应采用完整变更序列。
要点
- 应采用 build 2.4.16851 的 commit c9eff241;它包含版本号最后一次递增后合入的最终十进制舍入修复。
- GetNumericVariantFromJson 再次把 0.0 及小数部分全为零的形式解析为数值零,不再导致数值转换失败。
- GetExtended 与 GetNumericVariantFromJson 现在会把 1.2 等常见小数转换为最近的 IEEE double,而不是高出一个 ULP 的值。
- DoubleToAscii 修复科学计数法的标点生成,并在 CPU64 上应用 sticky bit 舍入,从而改善浮点值与文本的精确往返转换。
- 非 WIN32DELPHI 的 GetExtended 路径现在可处理最小 subnormal 与最大有限 double 边界,不再过早失败。
升级建议
应采用标记为 build 2.4.16851 的最终 revision c9eff241,而不只是带有相同 build 号的较早 commit。应避开 build 2.4.16844 至 2.4.16850,因为其中 GetNumericVariantFromJson 可能拒绝 0.0,而且输出与 parser 的边界处理仍不完整。升级后,请在所有交付的 Delphi 与 FPC 目标上重跑 JSON 数值、科学计数法和 double 精确往返测试。
8 条中的 8 条 · 上游 9 次提交
1
高
常见十进制小数现舍入到最近的 IEEE double
当小数 exponent 为 -1 至 -22 且累积整数不超过 MAX_SAFE_JS_INTEGER 时,mormot.core.text 的 GetExtended 与 mormot.core.variants 的 GetNumericVariantFromJson 使用 Clinger fast path。它们改为除以可精确表示的正十次幂,而不是乘以不精确的负十次幂;精确 bit 测试覆盖 1.2、0.1、2.675 及较小 JSON double。
修复
mormot.core.text+1
aa165fe9+87-10
core: correctly rounded GetExtended() and GetNumericVariantFromJson() decimals
影响
常见十进制文本解析出的 double 可能变化一个 ULP,变为正确舍入值;例如在受影响的 Pascal 路径上,1.2 不再变成 1.2000000000000002。FPC 与非 Win32 Delphi 的 GetExtended 调用方直接受益,而 GetNumericVariantFromJson 在 Delphi 与 FPC backend 上均得到修复。
建议升级
采用已 merge 的 c9eff241 head,并重跑依赖解析后 double bit 的精确数值比较、hash 或持久化值测试。
公开 API
GetExtendedbehaviour-changed — Pascal 路径上的常见十进制小数现在生成最近的 IEEE double。GetNumericVariantFromJsonbehaviour-changed — 符合条件的 JSON 小数现在生成最近的 IEEE double,不再产生一个 ULP 的舍入误差。
2
高
CPU64 格式化现保留正确舍入所需的 sticky digit
mormot.core.text 的 DoubleToAscii 现在与 CPU32 一样,会在 CPU64 上于请求精度之外仍有被丢弃 bit 时附加一个合成的非零 sticky digit。d2a_k_comp 还以 inline fixed-point 整数估算替代浮点对数运算;只要保留了小数位,指数输出就会写入小数点。
修复
mormot.core.text
f4433cf3+13-24
core: fixed DoubleToAscii()
影响
Delphi 64-bit 与 FPC 64-bit build 对接近舍入平局的值可能产生不同末位;现在会表示被丢弃的尾部,并按最近偶数舍入。序列化浮点字符串可更可靠地精确解析回原值,signature 不变。
建议升级
升级到最终 revision c9eff241,并在 CPU64 上重跑精确浮点序列化往返测试。
公开 API
DoubleToAsciibehaviour-changed — CPU64 舍入现在通过 sticky digit 计入被丢弃的非零 bit。
3
高
极端十进制 exponent 可到达有效 double 边界
mormot.core.text 中非 WIN32DELPHI 的 GetExtended 实现不再拒绝所有小于等于 -324 的 frac。对于可表示的 -342 至 -324 范围,它先缩放 d64,再应用剩余负十次幂;同时允许 frac 308 进入现有的 overflow-safe 缩放路径。
修复
mormot.core.text
56bb70cd+14-4
core: fixed GetExtended() on huge/tiny exponents
影响
FPC 与非 Win32 Delphi backend 现在可解析有效的最小 subnormal 和最大有限十进制值,不再报错或过早丢失。此 commit 不修改 Delphi Win32 x87 assembly 实现。
值得一看
如果输入校验依赖 GetExtended 返回的 err,请重新测试 exponent 的接受与拒绝边界。
公开 API
GetExtendedbehaviour-changed — Pascal 路径现在接受此前被过早拒绝的有效 double 极端 exponent。
4
高
JSON 小数零再次按数值处理
mormot.core.variants 的 GetNumericVariantFromJson 在一个或多个小数零后遇到 delimiter 时不再退出。它会区分小数点后缺少首位数字与已结束的全零小数部分;新增测试要求 0.0 和 0.000000000 返回 varInteger 零。
修复
mormot.core.variants
58178149+8-3
core: fixed regression in GetNumericVariantFromJson()
影响
带小数点的 JSON 数值零不再使该快速数值 parser 失败,也不会在高层转换路径中回退为非数值表示。接收 0.0 的 Delphi 与 FPC 服务重新获得与其他零写法相同的规范化整数零结果。
建议升级
请越过 build 2.4.16844–2.4.16850,并测试可能包含 0.0 或带尾随小数位零值的 JSON 字段。
公开 API
GetNumericVariantFromJsonbehaviour-changed — 小数部分全为零的 JSON 形式再次成功解析,并规范化为 varInteger 零。
5
中
零值 exponent 在缩放前走安全 fast path
mormot.core.text 的 Pascal GetExtended 路径在 v64 为零时,会先通过公共符号尾处理返回 signed zero,不再执行 exponent 缩放。极小 exponent 计算也被重组,在同一表达式中相乘 d64、1E-160 因子与剩余 inverse power。
修复
mormot.core.text
8b5a85a4+19-7
core: refine some GetExtended() specific cases
影响
FPC 与非 Win32 Delphi backend 可在无 range error 的情况下接受 0E400 和 0E-400,并保留负零。现有源码无需改动;Delphi Win32 继续使用独立 assembly parser。
公开 API
GetExtendedbehaviour-changed — 零值在 exponent 极大时仍有效,并保留符号。
6
中
科学计数格式不再输出位置错误的小数点
在 mormot.core.text 中,d2a_return_exponential 现在会先把 n_digits_have 限制到 n_digits_req,再决定是否写入小数点。separator 与小数有效数字一起输出,而不是在最终位数确定前写入。
修复
mormot.core.text
37212dc4+8-8
core: fixed DoubleToAscii() correctness of scientific notation
影响
现有 Delphi 与 FPC 代码继续使用相同的 DoubleToAscii signature,但边界科学计数字符串可能改为正确标点。若 consumer 按字节比较序列化浮点文本,应在采用完整变更序列后更新预期值。
值得一看
重跑会精确比较 DoubleToAscii 科学计数法输出的 golden-output 测试。
公开 API
DoubleToAsciibehaviour-changed — 科学计数输出仅在写入小数有效数字时添加小数点。
7
低
往返测试扩展到符号、数量级与精确 bit pattern
test.core.base 新增从 1.5E-19 到 2E19 的正负 DoubleToShort 用例、精确 QWord-to-double vector,以及带极大正负 exponent 的零值 GetExtended 检查。它还验证末尾含空白的 TimeSpan 输入。
测试
a155bf80+34-3
tests: enhanced double / text conversion coverage
影响
应用代码与公开 API 均无变化。扩展后的测试固定 Delphi 与 FPC 上的 formatter/parser 往返行为,并说明 GetExtended 的精确 bit 边界检查不用于 WIN32DELPHI。
8
低
转换测试新增精确边界 vector
test.core.base 为最小 subnormal、最大有限值及其他 double 边界新增精确 bit assertion,并覆盖正负科学计数法往返。其本地输出 helper 现在直接比较 ShortString 值。
测试
511fe932+25-8
tests: enhanced floating point conversion vectors
影响
应用代码与公开 API 均无变化。这些测试让后续 parser 与 formatter 边界修复可在 Delphi 和 FPC 上被检测,但 GetExtended 的精确 bit 检查仍排除 WIN32DELPHI。