模块契约Math API
线程与全局状态
所有数学函数都是无状态函数,可以并发调用。近似比较不再读取 xCore 的可变模式和容差,因此库、线程、协程和测试不会互相改变数学判断规则。
错误
数学函数为纯计算:合法输入不设置错误;非法参数(如近似比较的容差为负、量化步长为零)设置 XERR_ARGUMENT,经 xrtGetError() 取得。
设计契约
XRT_FEATURE_MATH 提供动态宿主和跨平台 C 代码需要的稳定数学补充层。它只依赖 core,不依赖随机数、线程或可变全局配置。
XRT 不重复包装全部 C 数学库。sin、cos、sqrt 等已有稳定 C 契约的函数仍直接使用 <math.h>;本模块保留的是常用组合操作、旧 CRT 兼容实现、统一特殊值语义和显式容差比较。
常量
常量值是固定 API 契约,应用不能通过预处理器覆盖。无穷与 NaN 使用标准 <math.h> 的 HUGE_VAL、INFINITY 和 NAN,不再创建重复别名。
范围与符号
xrtMathMin 与 xrtMathMax 在任一参数为 NaN 时传播 NaN,而不是像 C fmin/fmax 那样忽略单个 NaN。两个参数都是零时,min 选择负零,max 选择正零。
xrtMathClamp 使用闭区间,并保留旧版便捷规则:边界写反时自动交换。值或边界为 NaN 时按 value -> min -> max 顺序传播第一个 NaN。xrtMathSign 对负数、正数返回 -1、1,对正负零和 NaN 返回 0。
数值转换
xrtMathTrunc 向零截断,并保留零、NaN、无穷。xrtMathFract 返回 value - floor(value),因此 xrtMathFract(-1.25) == 0.75。xrtMathMod 保持 C fmod 的余数符号与特殊值规则。xrtMathRad 与 xrtMathDeg 使用固定 XRT_PI 转换角度。
特殊值
三个函数提供跨 CRT 一致的布尔结果。xrtMathIsInf 不通过 inf - inf 判断,因此不会为了分类主动执行无效的无穷运算。
兼容数学函数
这些导出函数为动态宿主和缺少部分 C99 符号的旧 Windows CRT 提供统一入口:
xrtMathLog1p 与 xrtMathExpm1 对接近零的输入使用短级数,避免先舍入掉微小差值,并保留输入负零的符号。xrtMathCbrt 保留负数符号,并在 pow 初值后执行牛顿修正。xrtMathHypot 先按绝对值缩放,降低直接计算 x*x + y*y 的上溢和下溢风险;任一参数为无穷时结果为正无穷,即使另一参数为 NaN。
函数的定义域、舍入、errno 和浮点异常继续遵循平台 C 数学环境。XRT 只固定上述组合语义,不伪造任意精度承诺。
旧 API 决策
- 删除
XRT_APPROX_DIFF、XRT_APPROX_PERCENT 和 xCore 容差字段。 xrtIntApprox 改为显式无溢出的 xrtMathIntNear。xrtNumApprox 改为同时表达绝对与相对容差的 xrtMathNear。- 常量缩短为
XRT_PI、XRT_TAU、XRT_E;删除对标准无穷和 NaN 的重复定义。 - 保留旧版稳定的 fract、hypot 和小值级数思路,同时修复整数差值溢出、
INT64_MIN 取绝对值溢出、隐藏全局竞态和特殊值含糊问题。
完整示例
examples/math/helpers/main.c:范围、负数小数部分、角度和稳定 hypot。examples/math/near/main.c:绝对、相对和整数容差。
xrtMathMin函数
返回两个浮点数中较小者;NaN 参与比较返回另一操作数之外的非确定侧(实现按 IEEE minNum 语义)。
double xrtMathMin(double fLeft, double fRight)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
fLeft | 输入 | — | 左值 |
fRight | 输入 | — | 右值 |
范例已编译验证
math/tour · 极值 · 观察
if ( (xrtMathMin(2.0, 3.0) != 2.0) ||
(xrtMathMin(3.0, 2.0) != 2.0) ||
(xrtMathMax(2.0, 3.0) != 3.0) ||
(xrtMathMax(3.0, 2.0) != 3.0) ||
(xrtMathMin(-1.0, 1.0) != -1.0) ) {
xrtMathMax函数
返回两个浮点数中较大者。
double xrtMathMax(double fLeft, double fRight)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
fLeft | 输入 | — | 左值 |
fRight | 输入 | — | 右值 |
xrtMathClamp函数
把值限制在 [fMin, fMax] 区间内。
double xrtMathClamp(double fValue, double fMin, double fMax)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
fValue | 输入 | — | 待限制值 |
fMin | 输入 | <= fMax | 下界 |
fMax | 输入 | — | 上界 |
范例已编译验证
math/helpers · 极值 · 观察
printf("clamp: %.1f\n", xrtMathClamp(12.0, 0.0, 10.0)); /* 超上界→10 */
xrtMathSign函数
返回浮点数的符号:负数为 -1、零为 0、正数为 +1。
int xrtMathSign(double fValue)
范例已编译验证
math/tour · 基础 · 观察
if ( (xrtMathSign(-5.0) != -1) ||
(xrtMathSign(5.0) != 1) ||
(xrtMathSign(0.0) != 0) ) {
xrtMathTrunc函数
向零截断小数部分。
double xrtMathTrunc(double fValue)
范例已编译验证
math/tour · 基础 · 观察
if ( (xrtMathTrunc(2.7) != 2.0) ||
(xrtMathTrunc(-2.7) != -2.0) ) {
xrtMathFract函数
返回小数部分 x - trunc(x),保持符号。
double xrtMathFract(double fValue)
范例已编译验证
math/helpers · 基础 · 观察
printf("fract: %.2f\n", xrtMathFract(-1.25)); /* -1.25→0.75 */
xrtMathMod函数
带符号取模(结果符号随被除数);除数为零返回 NaN。
double xrtMathMod(double fValue, double fDivisor)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
fValue | 输入 | — | 被除数 |
fDivisor | 输入 | 非零 | 除数 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
| 数值 | fValue - divisor * trunc(fValue/divisor) | — |
范例已编译验证
math/tour · 基础 · 观察
if ( !exampleNear(xrtMathMod(7.0, 3.0), 1.0) ||
!exampleNear(xrtMathMod(-7.0, 3.0), -1.0) ) {
xrtMathRad函数
角度转弧度。
double xrtMathRad(double fDegrees)
范例已编译验证
math/tour · 基础 · 观察
if ( !exampleNear(xrtMathRad(180.0), 3.14159265358979) ) {
xrtMathDeg函数
弧度转角度。
double xrtMathDeg(double fRadians)
范例已编译验证
math/helpers · 基础 · 观察
printf("angle: %.1f\n", xrtMathDeg(XRT_PI)); /* π rad→180° */
xrtMathIsNaN函数
判断是否 NaN。
bool xrtMathIsNaN(double fValue)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 是 NaN | — |
false | 非 NaN | 纯谓词 |
范例已编译验证
math/tour · 分类 · 观察
if ( !xrtMathIsNaN(fNaN) ||
xrtMathIsNaN(1.0) ||
xrtMathIsNaN(fInf) ||
!xrtMathIsInf(fInf) ||
xrtMathIsInf(1.0) ||
xrtMathIsInf(fNaN) ||
!xrtMathIsFinite(1.5) ||
xrtMathIsFinite(fNaN) ||
xrtMathIsFinite(fInf) ) {
xrtMathIsInf函数
判断是否无穷大(正或负)。
bool xrtMathIsInf(double fValue)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 是无穷 | — |
false | 有限或 NaN | 纯谓词 |
xrtMathIsFinite函数
判断是否有限值(非 NaN 且非无穷)。
bool xrtMathIsFinite(double fValue)
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 有限 | — |
false | NaN 或无穷 | 纯谓词 |
xrtMathLog2函数
以 2 为底的对数;非正值返回 NaN。
double xrtMathLog2(double fValue)
范例已编译验证
math/tour · 函数 · 观察
if ( !exampleNear(xrtMathLog2(8.0), 3.0) ||
!exampleNear(xrtMathLog2(1.0), 0.0) ||
!exampleNear(xrtMathExp2(10.0), 1024.0) ||
!exampleNear(xrtMathLog1p(0.0), 0.0) ||
!exampleNear(xrtMathExpm1(0.0), 0.0) ||
!exampleNear(xrtMathLog1p(1.0), 0.693147180559945) ||
!exampleNear(xrtMathExpm1(1.0), 1.718281828459045) ) {
xrtMathExp2函数
2 的幂;溢出返回无穷。
double xrtMathExp2(double fValue)
范例已编译验证
math/tour · 函数 · 观察
!exampleNear(xrtMathExp2(10.0), 1024.0) ||
xrtMathLog1p函数
计算 ln(1 + x),x 接近零时保持精度。
double xrtMathLog1p(double fValue)
xrtMathExpm1函数
计算 e^x - 1,x 接近零时保持精度。
double xrtMathExpm1(double fValue)
xrtMathCbrt函数
立方根;负数返回负根(与 pow(x, 1/3) 不同)。
double xrtMathCbrt(double fValue)
范例已编译验证
math/tour · 函数 · 观察
if ( !exampleNear(xrtMathCbrt(27.0), 3.0) ||
!exampleNear(xrtMathCbrt(-27.0), -3.0) ||
!exampleNear(xrtMathCbrt(0.0), 0.0) ) {
xrtMathHypot函数
计算 sqrt(x² + y²),中间过程不上溢。
double xrtMathHypot(double fX, double fY)
范例已编译验证
math/helpers · 函数 · 观察
printf("hypot: %.1f\n", xrtMathHypot(3.0, 4.0)); /* 勾股 3-4-5 */
xrtMathNear函数
使用显式绝对与相对容差比较两个浮点数:|L-R| <= max(abs, rel * max(|L|,|R|))。 有限数比较避免在求差或计算相对阈值时溢出为无穷。负值或 NaN 容差无效。
bool xrtMathNear(double fLeft, double fRight, double fAbsoluteTolerance, double fRelativeTolerance)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
fLeft | 输入 | — | 左值 |
fRight | 输入 | — | 右值 |
fAbsoluteTolerance | 输入 | >= 0 | 绝对容差 |
fRelativeTolerance | 输入 | >= 0 | 相对容差 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | 在容差内相等 | — |
false | 超出容差或容差无效 | 容差无效时设置 XERR_ARGUMENT |
错误- 负值或 NaN 容差:
XERR_ARGUMENT。正常的“不接近”返回 false,不设置新错误。
范例已编译验证
math/tour · 比较 · 观察
return xrtMathNear(fLeft, fRight, 1e-9, 0.0);
xrtMathIntNear函数
使用无符号绝对差容差比较两个 int64,计算过程不会溢出。
bool xrtMathIntNear(int64 iLeft, int64 iRight, uint64 iTolerance)
参数
| 参数 | 方向 | 约束 | 说明 |
|---|
iLeft | 输入 | — | 左值 |
iRight | 输入 | — | 右值 |
iTolerance | 输入 | — | 容差 |
返回值| 返回 | 含义 | 失败时状态 |
|---|
true | ‖L-R‖ <= iTolerance(含 INT64_MIN 边界) | — |
false | 超出容差 | 纯谓词 |
范例已编译验证
math/near · 比较 · 观察
xrtMathIntNear(1000, 1003, 5) ? "near" : "different");
常量索引常量
以下常量在本页所属头文件中定义,语义见公共头注释。
| 常量 | 说明 |
| XRT_E | 见头文件注释 |
| XRT_PI | 见头文件注释 |
| XRT_TAU | 见头文件注释 |