std::ratio în C++

O fracție calculată la compilare (numărător/numitor), folosită pentru unități precum milisecunde sau kilometri.

Sintaxă
std::ratio<Numarator, Numitor>
std::ratio_add<R1, R2>, std::ratio_multiply<R1, R2>, std::ratio_less<R1, R2>
std::milli, std::kilo, std::mega ...

Ce face std::ratio

std::ratio<N, D> (din <ratio>) nu este o valoare, ci un tip care reprezintă fracția N/D. Fracția este simplificată automat: std::ratio<2, 4>::num este 1, iar ::den este 2. Toate calculele se fac la compilare.

Operațiile sunt tot tipuri: std::ratio_add, ratio_subtract, ratio_multiply, ratio_divide și comparații ca std::ratio_less. Există prescurtări pentru prefixele SI: std::milli (1/1000), std::kilo (1000), std::mega etc. Cea mai cunoscută utilizare este în std::chrono::duration, unde std::milli înseamnă milisecunde.

Parametri

Parametru Descriere
Numarator Numărătorul (constantă întreagă).
Numitor Numitorul (diferit de 0, implicit 1).

Ce returnează

Un tip cu membrii constanți num și den.

Exemple

Exemplul 1: Fracții la compilare

#include <print>
#include <ratio>

int main() {
    using doua_patrimi = std::ratio<2, 4>;
    using o_treime = std::ratio<1, 3>;
    using suma = std::ratio_add<doua_patrimi, o_treime>;
    using produs = std::ratio_multiply<doua_patrimi, o_treime>;

    std::println("2/4 simplificat: {}/{}", doua_patrimi::num, doua_patrimi::den);
    std::println("1/2 + 1/3 = {}/{}", suma::num, suma::den);
    std::println("1/2 * 1/3 = {}/{}", produs::num, produs::den);
    std::println("1/3 < 1/2: {}", std::ratio_less_v<o_treime, doua_patrimi>);
}

Rezultat

2/4 simplificat: 1/2
1/2 + 1/3 = 5/6
1/2 * 1/3 = 1/6
1/3 < 1/2: true

Exemplul 2: Prefixe SI și std::chrono

std::chrono::milliseconds este o durată cu perioada std::milli.

#include <chrono>
#include <print>
#include <ratio>

int main() {
    std::println("milli = {}/{}", std::milli::num, std::milli::den);
    std::println("kilo  = {}/{}", std::kilo::num, std::kilo::den);

    using perioada = std::chrono::milliseconds::period;
    std::println("Perioada lui milliseconds: {}/{} s", perioada::num, perioada::den);

    std::chrono::duration<double, std::ratio<60>> minute(2.5);
    std::println("2.5 minute = {} secunde", std::chrono::duration<double>(minute).count());
}

Rezultat

milli = 1/1000
kilo  = 1000/1
Perioada lui milliseconds: 1/1000 s
2.5 minute = 150 secunde

Greșeli frecvente

  • Încerci std::ratio<1, 3> r; și r + 1: ratio nu este un număr la rulare, ci un tip. Pentru fracții la rulare ai nevoie de propria clasă.
  • Numitor 0 sau valori care depășesc std::intmax_t la operații: programul nu compilează.

Comenzi înrudite

  • std::gcd: Calculează cel mai mare divizor comun (gcd) și cel mai mic multiplu comun (lcm) a două numere întregi.
  • std::numeric_limits: Dă proprietățile unui tip numeric: valoarea maximă și minimă, precizia, dacă are semn, infinitul.