介绍
在WonderTrader的文件decimal.h中封装了一些用于浮点数(double)处理的工具函数,主要目的是解决浮点数精度误差带来的比较问题,以及进行一些常用运算(四舍五入、比较、取模等)。下面我们逐行详细解释每个函数的功能和实现逻辑。
🔹命名空间声明
namespace decimal { ... }
这将所有函数和常量包裹在 decimal 命名空间中,避免和其他代码冲突。
🔹EPSINON 常量定义
const double EPSINON = 1e-6;
用于浮点数比较的误差容忍值,表示在 1e-6 精度内认为两个浮点数相等。这是处理浮点误差的标准做法。
✅ 1. rnd:浮点数四舍五入
inline double rnd(double v, int exp = 1)
{return round(v * exp) / exp;
}
作用:
将浮点数 v 按 exp 精度进行四舍五入。
举例:
输入 | 输出 |
---|---|
rnd(3.14159, 100) | 3.14 |
rnd(3.14159, 1000) | 3.142 |
rnd(123.456, 1) | 123 |
exp 决定精度:100 表示保留两位小数,1000 表示三位。
✅ 2. eq:判断是否相等(考虑精度误差)
inline bool eq(double a, double b = 0.0) noexcept
{return(fabs(a - b) < EPSINON);
}
作用:
判断 a 和 b 是否“近似相等”,误差在 1e-6 以内。
说明:
使用 fabs(a - b) 代替 a == b 是因为浮点数存在精度问题,直接比较会出错。
举例:
eq(0.3333333, 1.0/3) // true,虽然严格上不相等
✅ 3. gt:大于判断(排除误差)
inline bool gt(double a, double b = 0.0) noexcept
{return a - b > EPSINON;
}
作用:
判断 a > b,但要求 a - b 必须大于一个误差量 EPSINON,否则认为两者相等
✅ 4. lt:小于判断(排除误差)
inline bool lt(double a, double b = 0.0) noexcept
{return b - a > EPSINON;
}
等价于判断 a < b,但考虑了浮点误差。
✅ 5. ge:大于等于判断
inline bool ge(double a, double b = 0.0) noexcept
{return gt(a, b) || eq(a, b);
}
即:如果 a > b 或 a ≈ b,则 a >= b。
✅ 6. le:小于等于判断
inline bool le(double a, double b = 0.0) noexcept
{return lt(a, b) || eq(a, b);
}
即:如果 a < b 或 a ≈ b,则 a <= b。
✅ 7. mod:浮点数“取模”
inline double mod(double a, double b)
{return a / b - round(a / b);
}
功能:
返回 a / b 与最接近的整数的偏差部分(不是传统意义上的“取余”,而是衡量 a 与 b 的整数倍的偏差)。
举例:
mod(10.2, 5) = 10.2/5 - round(10.2/5) = 2.04 - 2 = 0.04
mod(14.9, 5) = 2.98 - 3 = -0.02
用途:
可用于判断一个值是否接近某个周期的整数倍。例如:
if (fabs(mod(t, period)) < 1e-6) {// t 是 period 的整数倍(考虑浮点误差)
}
或者用来检查委托价格是否是价格最小变动单位(价差)PriceTick 的整数倍,即判断这个价格是否“合法”。
// 检查价格是否非零(为 0 就没必要检查 tick 合法性了)
if(!decimal::eq(entrust->getPrice(), 0))
{// 获取该合约最小价格变动单位(例如 0.2、0.01、0.0001 等)double pricetick = commInfo->getPriceTick();// 看价格是 tick 的几倍,可能是小数double v = entrust->getPrice() / pricetick;// 判断价格是否是 pricetick 的整数倍(即合法价格)if (!decimal::eq(decimal::mod(entrust->getPrice(), pricetick), 0)) {bPass = false;msg = "委托价格不合法";break;}
}
总结:这些函数解决的问题
函数 | 功能描述 | 关键意义 |
---|---|---|
rnd | 四舍五入到指定精度 | 格式化数值 |
eq | 判断两个浮点数近似相等 | 避免 a == b 失败 |
gt /lt | 判断严格大于/小于(排除误差) | 精确控制浮点比较 |
ge /le | 判断大于等于/小于等于 | 浮点稳定性判断 |
mod | 判断是否接近某个倍数(周期性) | 用于时间或频率周期判断 |