Skip to content

Trivia impact: rare

The Fraction Type That Reduces Itself

a fraction normalized before any object exists

using fraction = std::ratio<42, -56>;

std::cout << fraction::num << "/" << fraction::den << "\n";

Does this compile? What does it print?

Answer
-3/4

The denominator became positive and the fraction was reduced at compile time.

Why

[ratio.ratio] requires std::ratio<N, D>::num to be the signed numerator divided by the greatest common divisor, while den is the positive absolute denominator divided by that divisor. For 42/-56, the divisor is 14, yielding -3/4. std::ratio is a type with static constexpr members here, so no runtime fraction object performs the reduction.

Where it shows up

std::chrono::duration uses a ratio as its compile-time period, and the standard unit aliases such as std::milli are ratios too. Direct ratio use is uncommon, but it is the reason duration conversions can carry exact unit relationships in their types.

Takeaway: std::ratio<N, D> canonicalizes its sign and greatest common divisor.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry