概覽
std::ratio定義在<ratio>
文件中,提供了編譯期的比例計算功能。為std::chrono::duration提供基礎服務。
類定義
std::ratio是一個模板類,關鍵代碼摘錄如下(格式有調整):
- template<intmax_t _Nx, intmax_t _Dx = 1>
- struct ratio
- {
- static_assert(_Dx != 0, "zero denominator");
- static_assert(-INTMAX_MAX <= _Nx, "numerator too negative");
- static_assert(-INTMAX_MAX <= _Dx, "denominator too negative");
- static constexpr intmax_t num = _Sign_of<_Nx>::value
- * _Sign_of<_Dx>::value * _Abs<_Nx>::value / _Gcd<_Nx, _Dx>::value;
- static constexpr intmax_t den = _Abs<_Dx>::value / _Gcd<_Nx, _Dx>::value;
- typedef ratio<num, den> type;
- };
第一個參數_Nx
代表了分子,第二個參數 _Dx
代表了分母。
num
是計算后的分子,den
是計算后的分母。在duration轉換的時候會用到這兩個值。
注:這里的計算是指約分,可以看到傳入的分子和分母都除以了最大公約數。
num
是numerator
的縮寫,表示分子。
den
是denominator
的縮寫,表示分母。
預定義ratio
為了方便代碼的書寫,標准庫提供了如下定義:
Type | Definition |
---|---|
yocto | std::ratio<1, 1000000000000000000000000>, if std::intmax_t can represent the denominator |
zepto | std::ratio<1, 1000000000000000000000>, if std::intmax_t can represent the denominator |
atto | std::ratio<1, 1000000000000000000> |
femto | std::ratio<1, 1000000000000000> |
pico | std::ratio<1, 1000000000000> |
nano | std::ratio<1, 1000000000> |
micro | std::ratio<1, 1000000> |
milli | std::ratio<1, 1000> |
centi | std::ratio<1, 100> |
deci | std::ratio<1, 10> |
deca | std::ratio<10, 1> |
hecto | std::ratio<100, 1> |
kilo | std::ratio<1000, 1> |
mega | std::ratio<1000000, 1> |
giga | std::ratio<1000000000, 1> |
tera | std::ratio<1000000000000, 1> |
peta | std::ratio<1000000000000000, 1> |
exa | std::ratio<1000000000000000000, 1> |
zetta | std::ratio<1000000000000000000000, 1>, if std::intmax_t can represent the numerator |
yotta | std::ratio<1000000000000000000000000, 1>, if std::intmax_t can represent the numerator |
應用
如果想表示1/5,那么可以這樣寫std::ratio<1, 5>
。
回想我們在學習std::chrono::duration中遇到到的milli
的定義:
typedef ratio<1, 1000> milli;
,表示一千分之一,因為約定了基本計算單位是秒,所以milli
表示一千分之一秒。
示例代碼
- typedef std::chrono::duration<float, std::ratio<3, 1> > three_seconds;
- typedef std::chrono::duration<float, std::ratio<1, 10> > one_tenth_seconds;
- int main()
- {
- three_seconds s = std::chrono::duration_cast<three_seconds>(one_tenth_seconds(3));
- std::cout << "3 [1/10 seconds] equal to " << s.count() << " [3 seconds]\n";
- std::cin.get();
- }
參考資料
- vs源碼
- cppreference