19 General utilities library [utilities]

19.16 Compile-time rational arithmetic [ratio]

19.16.4 Arithmetic on ratios [ratio.arithmetic]

Each of the alias templates ratio_­add, ratio_­subtract, ratio_­multiply, and ratio_­divide denotes the result of an arithmetic computation on two ratios R1 and R2.
With X and Y computed (in the absence of arithmetic overflow) as specified by Table 55, each alias denotes a ratio<U, V> such that U is the same as ratio<X, Y>::num and V is the same as ratio<X, Y>::den.
If it is not possible to represent U or V with intmax_­t, the program is ill-formed.
Otherwise, an implementation should yield correct values of U and V.
If it is not possible to represent X or Y with intmax_­t, the program is ill-formed unless the implementation yields correct values of U and V.
Table 55 — Expressions used to perform ratio arithmetic
Type
Value of X
Value of Y
ratio_­add<R1, R2>
R1::num * R2::den +
R1::den * R2::den
R2::num * R1::den
ratio_­subtract<R1, R2>
R1::num * R2::den -
R1::den * R2::den
R2::num * R1::den
ratio_­multiply<R1, R2>
R1::num * R2::num
R1::den * R2::den
ratio_­divide<R1, R2>
R1::num * R2::den
R1::den * R2::num
[Example
:
static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::num == 1, "1/3+1/6 == 1/2");
static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::den == 2, "1/3+1/6 == 1/2");
static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::num == 1, "1/3*3/2 == 1/2");
static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::den == 2, "1/3*3/2 == 1/2");

// The following cases may cause the program to be ill-formed under some implementations
static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::num == 2,
  "1/MAX+1/MAX == 2/MAX");
static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::den == INT_MAX,
  "1/MAX+1/MAX == 2/MAX");
static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::num == 1,
  "1/MAX * MAX/2 == 1/2");
static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::den == 2,
  "1/MAX * MAX/2 == 1/2");
end example
]