模块契约Number

错误

错误域为 xrt.number:

  • XNUMBER_ERROR_CONFIG:不支持的基数或标志。
  • XNUMBER_ERROR_FORMAT:文本语法错误或存在未消费字符。
  • XNUMBER_ERROR_RANGE:整数溢出或有限浮点文本溢出为无穷。

空指针和无效视图使用公共参数错误。容量不足使用公共范围错误。

选择边界

需求入口
把整数按显式基数写入文本xrtIntWrite / xrtUIntWrite
写出最短可往返 doublexrtNumWrite
生成拥有型基础数字文本对应 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.c
  • examples/number/float/main.c
  • examples/number/format/main.c
  • tests/number/test_integer.c
  • tests/number/test_float.c
  • tests/number/test_float_long.c
  • tests/number/test_format.c
  • tests/number/test_format_property.c
  • tests/number/test_integer_oom.c
  • tests/number/test_float_oom.c
  • tests/number/test_format_oom.c
  • tests/single/test_single_number_integer.c
  • tests/single/test_single_number_float.c
  • tests/single/test_single_number_format.c

xnumberparseflag类型

数值文本解析标志。 默认严格解析完整文本;空白、进制前缀、数字分隔符和特殊浮点值均需显式开启。

值语义
XNUMBER_PARSE_SPACESPACE
XNUMBER_PARSE_PREFIX前缀
XNUMBER_PARSE_SEPARATORSEPARATOR
XNUMBER_PARSE_SPECIAL允许特殊值
typedef enum xnumberparseflag { XNUMBER_PARSE_SPACE = UINT32_C(0x00000001), XNUMBER_PARSE_PREFIX = UINT32_C(0x00000002), XNUMBER_PARSE_SEPARATOR = UINT32_C(0x00000004), XNUMBER_PARSE_SPECIAL = UINT32_C(0x00000008)

xnumbererror类型

数值模块稳定错误码。

值语义
XNUMBER_ERROR_CONFIG配置非法
XNUMBER_ERROR_FORMAT格式非法
XNUMBER_ERROR_RANGE范围越界
typedef enum xnumbererror { XNUMBER_ERROR_CONFIG = 1201, XNUMBER_ERROR_FORMAT = 1202, XNUMBER_ERROR_RANGE = 1203 } xnumbererror;

xnumberwriteflag类型

整数文本输出标志;默认使用小写数字且不添加前缀或正号。

值语义
XNUMBER_UPPER大写
XNUMBER_PREFIX前缀
XNUMBER_PLUS非负值输出 + 号
typedef enum xnumberwriteflag { XNUMBER_UPPER = UINT32_C(0x00000001), XNUMBER_PREFIX = UINT32_C(0x00000002), XNUMBER_PLUS = UINT32_C(0x00000004)

xnumberfloatflag类型

浮点文本输出标志。 默认保留整数型 double 的 .0;紧凑模式只保留数值往返所需字符。

值语义
XNUMBER_FLOAT_COMPACT紧凑形式
typedef enum xnumberfloatflag { XNUMBER_FLOAT_COMPACT = UINT32_C(0x00000001)
解析

xrtUIntWrite函数

按 2 到 36 进制写出无符号整数;输出为空且容量为零时只查询长度。

bool xrtUIntWrite(uint64 iValue, uint32 iBase, char* sOutput, size_t iCapacity, size_t* pOutputSize, uint32 iFlags)

参数

参数方向约束说明
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 只影响非负值。

bool xrtIntWrite(int64 iValue, uint32 iBase, char* sOutput, size_t iCapacity, size_t* pOutputSize, uint32 iFlags)

参数

参数方向约束说明
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 · 缓冲写入

	(void)xrtIntWrite(-42, 10u, NULL, 0u, &iNeed, 0u);

xrtUIntString函数

写出无符号整数并返回由 xrtFree 释放的末尾补零文本。

str xrtUIntString(uint64 iValue, uint32 iBase, uint32 iFlags)

参数

参数方向约束说明
iValue输入—要写出的值
iBase输入2–36目标进制
iFlags输入—XNUMBER_* 输出标志
返回值
返回含义失败时状态
非空零结尾文本,xrtFree 释放—
NULL失败xrt.number 错误
错误
  • xrt.number / XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制不在 2–36 或标志组合非法
  • XERR_MEMORY — 分配失败

范例已编译验证

variants · 分配写入

	str sText = xrtUIntString(UINT64_C(4294967296), 10u, 0u);

xrtIntString函数

写出有符号整数并返回由 xrtFree 释放的末尾补零文本。

str xrtIntString(int64 iValue, uint32 iBase, uint32 iFlags)

参数

参数方向约束说明
iValue输入—要写出的值
iBase输入2–36目标进制
iFlags输入—XNUMBER_* 输出标志
返回值
返回含义失败时状态
非空零结尾文本,xrtFree 释放—
NULL失败xrt.number 错误
错误
  • xrt.number / XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制不在 2–36 或标志组合非法
  • XERR_MEMORY — 分配失败

范例已编译验证

integer · 分配写入

	sDecimal = xrtIntString(iValue, 10, 0);

xrtUIntParse函数

严格解析无符号整数;iBase 为零时默认十进制,并在允许前缀时自动识别 0b、0o、0x。

bool xrtUIntParse(xstrview Text, uint32 iBase, uint32 iFlags, uint64* pValue)

参数

参数方向约束说明
Text输入借用输入文本
iBase输入0 或 2–360 = 十进制 + 前缀识别
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函数

严格解析有符号整数;正负号必须位于可选进制前缀之前,溢出时保持输出不变。

bool xrtIntParse(xstrview Text, uint32 iBase, uint32 iFlags, int64* pValue)

参数

参数方向约束说明
Text输入借用输入文本
iBase输入0 或 2–360 = 十进制 + 前缀识别
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 均有稳定表示。

bool xrtNumWrite(double fValue, char* sOutput, size_t iCapacity, size_t* pOutputSize, uint32 iFlags)

参数

参数方向约束说明
fValue输入—要写出的值
sOutput输出允许空空 + 零容量 = 查询长度
iCapacity输入—缓冲容量,须含末尾零字节
pOutputSize输出非空接收不含零字节的长度
iFlags输入—XNUMBER_* 浮点标志
返回值
返回含义失败时状态
true已写入并补末尾零—
false参数、标志或容量失败XERR_ARGUMENT 等
错误
  • XERR_ARGUMENT — pOutputSize 为空或输出与容量组合非法
  • xrt.number / XNUMBER_ERROR_CONFIG(XERR_VALUE) — 标志组合非法
  • XERR_RANGE — 容量不足(需含末尾零字节);不写半个结果

范例已编译验证

variants · 缓冲写入

	if ( xrtNumWrite(2.5, Buffer, sizeof(Buffer), &iNeed, 0u) ) {

xrtNumString函数

写出 double 并返回由 xrtFree 释放的末尾补零文本。

str xrtNumString(double fValue, uint32 iFlags)

参数

参数方向约束说明
fValue输入—要写出的值
iFlags输入—XNUMBER_* 浮点标志
返回值
返回含义失败时状态
非空零结尾文本,xrtFree 释放—
NULL失败xrt.number 错误
错误
  • xrt.number / XNUMBER_ERROR_CONFIG(XERR_VALUE) — 进制不在 2–36 或标志组合非法
  • XERR_MEMORY — 分配失败

范例已编译验证

float · 分配写入

	sText = xrtNumString(fValue, 0);

xrtNumParse函数

严格解析完整十进制浮点文本并执行 IEEE-754 正确舍入;特殊值和分隔符需显式开启。

bool xrtNumParse(xstrview Text, uint32 iFlags, double* pValue)

参数

参数方向约束说明
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函数

按照展示格式写出有符号整数;输出为空且容量为零时只查询长度。

bool xrtIntFormatTo(int64 iValue, xstrview Format, char* sOutput, size_t iCapacity, size_t* pOutputSize)

参数

参数方向约束说明
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函数

按照展示格式写出无符号整数。

bool xrtUIntFormatTo(uint64 iValue, xstrview Format, char* sOutput, size_t iCapacity, size_t* pOutputSize)

参数

参数方向约束说明
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,固定支持正确舍入、负零和特殊值。

bool xrtNumFormatTo(double fValue, xstrview Format, char* sOutput, size_t iCapacity, size_t* pOutputSize)

参数

参数方向约束说明
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 释放的零结尾字符串。

str xrtIntFormat(int64 iValue, xstrview Format)

参数

参数方向约束说明
iValue输入—要写出的值
Format输入借用展示格式
返回值
返回含义失败时状态
非空零结尾文本,xrtFree 释放—
NULL失败xrt.number 错误
错误
  • xrt.number / XNUMBER_ERROR_FORMAT(XERR_VALUE) — 格式语法非法
  • xrt.number / XNUMBER_ERROR_RANGE(XERR_RANGE) — 宽度或精度超出实现上限
  • XERR_MEMORY — 分配失败

范例已编译验证

format · 分配格式化

	str sInteger = xrtIntFormat(
		INT64_C(-123456789), XRT_STR_LITERAL(",d"));

xrtUIntFormat函数

按照展示格式格式化无符号整数并返回由 xrtFree 释放的零结尾字符串。

str xrtUIntFormat(uint64 iValue, xstrview Format)

参数

参数方向约束说明
iValue输入—要写出的值
Format输入借用展示格式
返回值
返回含义失败时状态
非空零结尾文本,xrtFree 释放—
NULL失败xrt.number 错误
错误
  • xrt.number / XNUMBER_ERROR_FORMAT(XERR_VALUE) — 格式语法非法
  • xrt.number / XNUMBER_ERROR_RANGE(XERR_RANGE) — 宽度或精度超出实现上限
  • XERR_MEMORY — 分配失败

范例已编译验证

format · 分配格式化

	str sHex = xrtUIntFormat(
		UINT64_C(0xDEADBEEF), XRT_STR_LITERAL("#_X"));

xrtNumFormat函数

按照展示格式格式化 double 并返回由 xrtFree 释放的零结尾字符串。

str xrtNumFormat(double fValue, xstrview Format)

参数

参数方向约束说明
fValue输入—要写出的值
Format输入借用展示格式
返回值
返回含义失败时状态
非空零结尾文本,xrtFree 释放—
NULL失败xrt.number 错误
错误
  • xrt.number / XNUMBER_ERROR_FORMAT(XERR_VALUE) — 格式语法非法
  • xrt.number / XNUMBER_ERROR_RANGE(XERR_RANGE) — 宽度或精度超出实现上限
  • XERR_MEMORY — 分配失败

范例已编译验证

format · 分配格式化

	str sFloat = xrtNumFormat(
		1234567.895, XRT_STR_LITERAL(",.2f"));

xrtIntFormatSized函数

分配有符号整数的精确字节结果,按 xrtIntFormatTo 的格式合同处理。

str xrtIntFormatSized(int64 iValue, xstrview Format, size_t* pOutputSize)

参数

参数方向约束说明
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 相同。

str xrtUIntFormatSized(uint64 iValue, xstrview Format, size_t* pOutputSize)

参数

参数方向约束说明
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 相同。

str xrtNumFormatSized(double fValue, xstrview Format, size_t* pOutputSize)

参数

参数方向约束说明
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见头文件注释