概覽
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
