模块契约Number
错误
错误域为 xrt.number:
XNUMBER_ERROR_CONFIG:不支持的基数或标志。XNUMBER_ERROR_FORMAT:文本语法错误或存在未消费字符。XNUMBER_ERROR_RANGE:整数溢出或有限浮点文本溢出为无穷。
空指针和无效视图使用公共参数错误。容量不足使用公共范围错误。
选择边界
| 需求 | 入口 |
|---|---|
| 把整数按显式基数写入文本 | xrtIntWrite / xrtUIntWrite |
写出最短可往返 double | xrtNumWrite |
| 生成拥有型基础数字文本 | 对应 String 入口 |
| 严格解析完整字段 | xrtIntParse / xrtUIntParse / xrtNumParse |
| 生成宽度、分组、精度等展示文本 | 对应 FormatTo / Format 入口 |
三个 Parse 入口都要求完整消费传入视图。Number 不保留旧 JNUM 的前缀解析器,也不会把非法输入和数值零折叠为同一个结果。在 CSV、DSL 或协议流中扫描 token 时,词法层应先确定 token 边界,再把精确子视图交给 Number;不能用成功解析前缀来证明整个字段合法。
JSON 数字由 JSON 词法层施加更窄语法,再复用精确数值转换。true、false 和 null 不是数字,也不会由 Number 解析。十进制整数超出 uint64 或 int64 时返回范围错误,不会静默退化为可能丢失精度的 double。需要任意精度整数时应保留原始文本或接入独立 BigInt 实现。
整数
number_integer 保留旧版 jnum 两位十进制查表的高效思路,但不保留错误契约。旧 xrtU32ToStr / xrtU64ToStr 的名称与十六进制行为不一致,旧 xrtI64ToStr 对 INT64_MIN 取负会产生未定义行为,旧 xrtStrTo* 还会把非法输入和数值零折叠成同一个结果;新 API 均已消除这些边界。
浮点
number_float 保留旧版适合动态宿主和跨平台 C 的使用语义:
- 整数型
double默认保留.0; - 保留
-0.0的符号; - 使用小写
e和显式指数符号; - 稳定写出
nan、inf、-inf。
旧版浮点核心不能保证任意 IEEE-754 位模式往返,且解析存在严格别名和静默截断问题。新实现的语法层由 XRT 编写,正确舍入内核精炼自 yyjson 的 Eisel-Lemire、固定栈 BigInt 和 Schubfach 实现。它不依赖 libc strtod、printf 或当前区域设置。
展示格式
number_format 复用整数写出和精确 double 底座,提供调用方缓冲区与一次分配两层 API:
三个 To 接口都支持 output == NULL && capacity == 0 的精确长度查询。容量不足时通过 outputSize 返回所需长度,目标保持不变;实际容量必须包含末尾零。三个分配接口返回由 xrtFree 释放的字符串。
示例与测试
examples/number/integer/main.cexamples/number/float/main.cexamples/number/format/main.ctests/number/test_integer.ctests/number/test_float.ctests/number/test_float_long.ctests/number/test_format.ctests/number/test_format_property.ctests/number/test_integer_oom.ctests/number/test_float_oom.ctests/number/test_format_oom.ctests/single/test_single_number_integer.ctests/single/test_single_number_float.ctests/single/test_single_number_format.c
xnumberparseflag类型
数值文本解析标志。 默认严格解析完整文本;空白、进制前缀、数字分隔符和特殊浮点值均需显式开启。
| 值 | 语义 |
|---|---|
XNUMBER_PARSE_SPACE | SPACE |
XNUMBER_PARSE_PREFIX | 前缀 |
XNUMBER_PARSE_SEPARATOR | SEPARATOR |
XNUMBER_PARSE_SPECIAL | 允许特殊值 |
xnumbererror类型
数值模块稳定错误码。
| 值 | 语义 |
|---|---|
XNUMBER_ERROR_CONFIG | 配置非法 |
XNUMBER_ERROR_FORMAT | 格式非法 |
XNUMBER_ERROR_RANGE | 范围越界 |
xnumberwriteflag类型
整数文本输出标志;默认使用小写数字且不添加前缀或正号。
| 值 | 语义 |
|---|---|
XNUMBER_UPPER | 大写 |
XNUMBER_PREFIX | 前缀 |
XNUMBER_PLUS | 非负值输出 + 号 |
xnumberfloatflag类型
浮点文本输出标志。 默认保留整数型 double 的 .0;紧凑模式只保留数值往返所需字符。
| 值 | 语义 |
|---|---|
XNUMBER_FLOAT_COMPACT | 紧凑形式 |
xrtUIntWrite函数
按 2 到 36 进制写出无符号整数;输出为空且容量为零时只查询长度。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | — | 要写出的值 |
iBase | 输入 | 2–36 | 目标进制 |
sOutput | 输出 | 允许空 | 空 + 零容量 = 查询长度 |
iCapacity | 输入 | — | 缓冲容量,须含末尾零字节 |
pOutputSize | 输出 | 非空 | 接收不含零字节的长度 |
iFlags | 输入 | — | XNUMBER_* 输出标志 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已写入并补末尾零 | — |
false | 参数、配置或容量失败 | XERR_ARGUMENT 等 |
XERR_ARGUMENT—pOutputSize为空、输出与容量组合非法或与输出区间重叠xrt.number/XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制不在 2–36 或标志组合非法XERR_RANGE— 容量不足(需含末尾零字节);失败不写半个结果,pOutputSize仍返回所需长度
范例已编译验证
variants · 缓冲写入
if ( xrtUIntWrite(UINT64_C(300), 16u, Buffer, sizeof(Buffer), &iNeed, 0u) ) {
xrtIntWrite函数
按 2 到 36 进制写出有符号整数;负号位于进制前缀之前,XNUMBER_PLUS 只影响非负值。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | — | 要写出的值 |
iBase | 输入 | 2–36 | 目标进制 |
sOutput | 输出 | 允许空 | 空 + 零容量 = 查询长度 |
iCapacity | 输入 | — | 缓冲容量,须含末尾零字节 |
pOutputSize | 输出 | 非空 | 接收不含零字节的长度 |
iFlags | 输入 | — | XNUMBER_* 输出标志 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已写入并补末尾零 | — |
false | 参数、配置或容量失败 | XERR_ARGUMENT 等 |
XERR_ARGUMENT—pOutputSize为空、输出与容量组合非法或与输出区间重叠xrt.number/XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制不在 2–36 或标志组合非法XERR_RANGE— 容量不足(需含末尾零字节);失败不写半个结果,pOutputSize仍返回所需长度
xrtUIntString函数
写出无符号整数并返回由 xrtFree 释放的末尾补零文本。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | — | 要写出的值 |
iBase | 输入 | 2–36 | 目标进制 |
iFlags | 输入 | — | XNUMBER_* 输出标志 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 零结尾文本,xrtFree 释放 | — |
NULL | 失败 | xrt.number 错误 |
xrt.number/XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制不在 2–36 或标志组合非法XERR_MEMORY— 分配失败
xrtIntString函数
写出有符号整数并返回由 xrtFree 释放的末尾补零文本。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | — | 要写出的值 |
iBase | 输入 | 2–36 | 目标进制 |
iFlags | 输入 | — | XNUMBER_* 输出标志 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 零结尾文本,xrtFree 释放 | — |
NULL | 失败 | xrt.number 错误 |
xrt.number/XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制不在 2–36 或标志组合非法XERR_MEMORY— 分配失败
xrtUIntParse函数
严格解析无符号整数;iBase 为零时默认十进制,并在允许前缀时自动识别 0b、0o、0x。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
Text | 输入 | 借用 | 输入文本 |
iBase | 输入 | 0 或 2–36 | 0 = 十进制 + 前缀识别 |
iFlags | 输入 | — | XNUMBER_* 解析标志 |
pValue | 输出 | 非空 | 接收结果,失败保持不变 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已解析 | — |
false | 文本、配置非法或溢出 | xrt.number 错误 |
XERR_ARGUMENT—pValue为空xrt.number/XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制或标志组合非法xrt.number/XNUMBER_ERROR_FORMAT(XERR_PROTOCOL) — 文本为空、符号错位、包含越基数数字或以分隔符结尾xrt.number/XNUMBER_ERROR_RANGE(XERR_RANGE) — 数值溢出目标类型,输出保持不变
范例已编译验证
variants · 严格解析
if ( sText == NULL || !xrtUIntParse(XRT_STR_LITERAL("4294967296"),
10u, 0u, &iValue) ) {
xrtIntParse函数
严格解析有符号整数;正负号必须位于可选进制前缀之前,溢出时保持输出不变。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
Text | 输入 | 借用 | 输入文本 |
iBase | 输入 | 0 或 2–36 | 0 = 十进制 + 前缀识别 |
iFlags | 输入 | — | XNUMBER_* 解析标志 |
pValue | 输出 | 非空 | 接收结果,失败保持不变 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已解析 | — |
false | 文本、配置非法或溢出 | xrt.number 错误 |
XERR_ARGUMENT—pValue为空xrt.number/XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制或标志组合非法xrt.number/XNUMBER_ERROR_FORMAT(XERR_PROTOCOL) — 文本为空、符号错位、包含越基数数字或以分隔符结尾xrt.number/XNUMBER_ERROR_RANGE(XERR_RANGE) — 数值溢出目标类型,输出保持不变
范例已编译验证
integer · 严格解析
if ( !xrtIntParse(XRT_STR_LITERAL(" -9_223_372_036_854_775_808 "),
10, (uint32)XNUMBER_PARSE_SPACE |
(uint32)XNUMBER_PARSE_SEPARATOR, &iValue) ) {
xrtNumWrite函数
写出 IEEE-754 double 的最短往返文本;负零、无穷和 NaN 均有稳定表示。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
fValue | 输入 | — | 要写出的值 |
sOutput | 输出 | 允许空 | 空 + 零容量 = 查询长度 |
iCapacity | 输入 | — | 缓冲容量,须含末尾零字节 |
pOutputSize | 输出 | 非空 | 接收不含零字节的长度 |
iFlags | 输入 | — | XNUMBER_* 浮点标志 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已写入并补末尾零 | — |
false | 参数、标志或容量失败 | XERR_ARGUMENT 等 |
XERR_ARGUMENT—pOutputSize为空或输出与容量组合非法xrt.number/XNUMBER_ERROR_CONFIG(XERR_VALUE) — 标志组合非法XERR_RANGE— 容量不足(需含末尾零字节);不写半个结果
xrtNumString函数
写出 double 并返回由 xrtFree 释放的末尾补零文本。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
fValue | 输入 | — | 要写出的值 |
iFlags | 输入 | — | XNUMBER_* 浮点标志 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 零结尾文本,xrtFree 释放 | — |
NULL | 失败 | xrt.number 错误 |
xrt.number/XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制不在 2–36 或标志组合非法XERR_MEMORY— 分配失败
xrtNumParse函数
严格解析完整十进制浮点文本并执行 IEEE-754 正确舍入;特殊值和分隔符需显式开启。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
Text | 输入 | 借用 | 输入文本 |
iFlags | 输入 | — | XNUMBER_* 解析标志 |
pValue | 输出 | 非空 | 接收结果,失败保持不变 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已解析 | — |
false | 文本、标志非法或超范围 | xrt.number 错误 |
XERR_ARGUMENT—pValue为空xrt.number/XNUMBER_ERROR_CONFIG(XERR_VALUE) — 标志组合非法xrt.number/XNUMBER_ERROR_FORMAT(XERR_PROTOCOL) — 文本为空、格式非法或特殊值未显式允许xrt.number/XNUMBER_ERROR_RANGE(XERR_RANGE) — 数值超出 double 可表示范围
范例已编译验证
float · 严格解析
if ( !xrtNumParse(
XRT_STR_LITERAL(" -1_234.567_890e-2 "),
(uint32)XNUMBER_PARSE_SPACE |
(uint32)XNUMBER_PARSE_SEPARATOR,
&fValue
) ) {
xrtIntFormatTo函数
按照展示格式写出有符号整数;输出为空且容量为零时只查询长度。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | — | 要写出的值 |
Format | 输入 | 借用 | 展示格式 |
sOutput | 输出 | 允许空 | 空 + 零容量 = 查询长度 |
iCapacity | 输入 | — | 缓冲容量,须含末尾零字节 |
pOutputSize | 输出 | 非空 | 接收不含零字节的长度 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已写入并补末尾零 | — |
false | 格式、参数或容量失败 | xrt.number 错误等 |
XERR_ARGUMENT—pOutputSize为空或输出与容量组合非法xrt.number/XNUMBER_ERROR_FORMAT(XERR_VALUE) — 格式语法非法xrt.number/XNUMBER_ERROR_RANGE(XERR_RANGE) — 宽度或精度超出实现上限XERR_RANGE— 容量不足(需含末尾零字节);不写半个结果
范例已编译验证
variants · 缓冲格式化
if ( xrtIntFormatTo(-1234567, XRT_STR_LITERAL(",d"),
Buffer, sizeof(Buffer), &iNeed) ) {
xrtUIntFormatTo函数
按照展示格式写出无符号整数。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | — | 要写出的值 |
Format | 输入 | 借用 | 展示格式 |
sOutput | 输出 | 允许空 | 空 + 零容量 = 查询长度 |
iCapacity | 输入 | — | 缓冲容量,须含末尾零字节 |
pOutputSize | 输出 | 非空 | 接收不含零字节的长度 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已写入并补末尾零 | — |
false | 格式、参数或容量失败 | xrt.number 错误等 |
XERR_ARGUMENT—pOutputSize为空或输出与容量组合非法xrt.number/XNUMBER_ERROR_FORMAT(XERR_VALUE) — 格式语法非法xrt.number/XNUMBER_ERROR_RANGE(XERR_RANGE) — 宽度或精度超出实现上限XERR_RANGE— 容量不足(需含末尾零字节);不写半个结果
范例已编译验证
variants · 缓冲格式化
if ( xrtUIntFormatTo(UINT64_C(255), XRT_STR_LITERAL("#X"),
Buffer, sizeof(Buffer), &iNeed) ) {
xrtNumFormatTo函数
按照展示格式写出 double,固定支持正确舍入、负零和特殊值。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
fValue | 输入 | — | 要写出的值 |
Format | 输入 | 借用 | 展示格式 |
sOutput | 输出 | 允许空 | 空 + 零容量 = 查询长度 |
iCapacity | 输入 | — | 缓冲容量,须含末尾零字节 |
pOutputSize | 输出 | 非空 | 接收不含零字节的长度 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已写入并补末尾零 | — |
false | 格式、参数或容量失败 | xrt.number 错误等 |
XERR_ARGUMENT—pOutputSize为空或输出与容量组合非法xrt.number/XNUMBER_ERROR_FORMAT(XERR_VALUE) — 格式语法非法xrt.number/XNUMBER_ERROR_RANGE(XERR_RANGE) — 宽度或精度超出实现上限XERR_RANGE— 容量不足(需含末尾零字节);不写半个结果
范例已编译验证
variants · 缓冲格式化
if ( xrtNumFormatTo(3.5, XRT_STR_LITERAL(".2f"),
Buffer, sizeof(Buffer), &iNeed) ) {
xrtIntFormat函数
按照展示格式格式化有符号整数并返回由 xrtFree 释放的零结尾字符串。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | — | 要写出的值 |
Format | 输入 | 借用 | 展示格式 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 零结尾文本,xrtFree 释放 | — |
NULL | 失败 | xrt.number 错误 |
xrt.number/XNUMBER_ERROR_FORMAT(XERR_VALUE) — 格式语法非法xrt.number/XNUMBER_ERROR_RANGE(XERR_RANGE) — 宽度或精度超出实现上限XERR_MEMORY— 分配失败
xrtUIntFormat函数
按照展示格式格式化无符号整数并返回由 xrtFree 释放的零结尾字符串。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | — | 要写出的值 |
Format | 输入 | 借用 | 展示格式 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 零结尾文本,xrtFree 释放 | — |
NULL | 失败 | xrt.number 错误 |
xrt.number/XNUMBER_ERROR_FORMAT(XERR_VALUE) — 格式语法非法xrt.number/XNUMBER_ERROR_RANGE(XERR_RANGE) — 宽度或精度超出实现上限XERR_MEMORY— 分配失败
xrtNumFormat函数
按照展示格式格式化 double 并返回由 xrtFree 释放的零结尾字符串。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
fValue | 输入 | — | 要写出的值 |
Format | 输入 | 借用 | 展示格式 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 零结尾文本,xrtFree 释放 | — |
NULL | 失败 | xrt.number 错误 |
xrt.number/XNUMBER_ERROR_FORMAT(XERR_VALUE) — 格式语法非法xrt.number/XNUMBER_ERROR_RANGE(XERR_RANGE) — 宽度或精度超出实现上限XERR_MEMORY— 分配失败
xrtIntFormatSized函数
分配有符号整数的精确字节结果,按 xrtIntFormatTo 的格式合同处理。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | 值 | 有符号整数 |
Format | 输入 | 借用 | 精确字节格式视图 |
pOutputSize | 输出 | 必须非空,不与 Format 重叠 | 不含末尾终止零的字节长度 |
非空为独立拥有的零结尾分配,由 xrtFree 释放。可以包含内嵌零。 普通失败返回 NULL,输出长度为零;输出槽与输入重叠时拒绝并保持输入不变。
沿用 To 的格式和范围错误;参数槽无效报 XERR_ARGUMENT,分配失败报 XERR_MEMORY。
范例已编译验证
见 format,以下示例保留精确长度:
size_t size;
str text = xrtIntFormatSized(0, XRT_STR_LITERAL("4c"), &size);
/* 成功时 size == 4,text 是三个空格和 U+0000。 */
xrtFree(text);
xrtUIntFormatSized函数
无符号版本,所有权、精确长度、输出槽和失败合同与 xrtIntFormatSized 相同。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
iValue | 输入 | 值 | 完整 uint64 |
Format | 输入 | 借用 | 精确字节格式视图 |
pOutputSize | 输出 | 必须非空,不与 Format 重叠 | 不含末尾终止零的字节长度 |
独立分配或 NULL,长度与清理合同相同。
沿用 xrtUIntFormatTo;另可能有参数槽或内存错误。
范例已编译验证
见 format。
size_t size;
str text = xrtUIntFormatSized(UINT64_MAX, XRT_STR_LITERAL("X"), &size);
xrtFree(text);
xrtNumFormatSized函数
double 版本,所有权、精确长度、输出槽和失败合同与 xrtIntFormatSized 相同。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
fValue | 输入 | 值 | double |
Format | 输入 | 借用 | 精确字节格式视图 |
pOutputSize | 输出 | 必须非空,不与 Format 重叠 | 不含末尾终止零的字节长度 |
独立分配或 NULL,长度与清理合同相同。
沿用 xrtNumFormatTo;另可能有参数槽或内存错误。
范例已编译验证
见 format。
size_t size;
str text = xrtNumFormatSized(-0.0, XRT_STR_LITERAL(".2f"), &size);
xrtFree(text);
常量索引常量
以下常量在本页所属头文件中定义,语义见公共头注释。
| 常量 | 说明 |
|---|---|
| XNUMBER_ERROR_CONFIG | 见头文件注释 |
| XNUMBER_ERROR_FORMAT | 见头文件注释 |
| XNUMBER_ERROR_RANGE | 见头文件注释 |
| XNUMBER_FLOAT_COMPACT | 见头文件注释 |
| XNUMBER_PARSE_PREFIX | 见头文件注释 |
| XNUMBER_PARSE_SEPARATOR | 见头文件注释 |
| XNUMBER_PARSE_SPACE | 见头文件注释 |
| XNUMBER_PARSE_SPECIAL | 见头文件注释 |
| XNUMBER_PLUS | 见头文件注释 |
| XNUMBER_PREFIX | 见头文件注释 |
| XNUMBER_UPPER | 见头文件注释 |