介紹
在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 | 判斷是否接近某個倍數(周期性) | 用于時間或頻率周期判斷 |