[ratio.arithmetic]

# 21 Metaprogramming library [[meta]](./#meta)

## 21.5 Compile-time rational arithmetic [[ratio]](ratio#arithmetic)

### 21.5.4 Arithmetic on ratios [ratio.arithmetic]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L7151)

Each of the alias templates ratio_add, ratio_subtract, ratio_multiply,
and ratio_divide denotes the result of an arithmetic computation on tworatios R1 and R2[.](#1.sentence-1)

With X and Y computed (in the
absence of arithmetic overflow) as specified by Table [65](#tab:ratio.arithmetic "Table 65: Expressions used to perform ratio arithmetic"), each alias
denotes a ratio<U, V> such that U is the same as ratio<X, Y>​::​num andV is the same as ratio<X, Y>​::​den[.](#1.sentence-2)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L7163)

If it is not possible to represent U or V with intmax_t, the program is
ill-formed[.](#2.sentence-1)

Otherwise, an implementation should yield correct values of U andV[.](#2.sentence-2)

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 andV[.](#2.sentence-3)

Table [65](#tab:ratio.arithmetic) — Expressions used to perform ratio arithmetic [[tab:ratio.arithmetic]](./tab:ratio.arithmetic)  

| [ð](#tab:ratio.arithmetic-row-1)<br>**Type** | **Value of X** | **Value of Y** |
| --- | --- | --- |
| [ð](#tab:ratio.arithmetic-row-2)<br>ratio_add<R1, R2> | R1​::​num * R2​::​den + | R1​::​den * R2​::​den |
| [ð](#tab:ratio.arithmetic-row-3) | R2​::​num * R1​::​den |  |
| [ð](#tab:ratio.arithmetic-row-4)<br>ratio_subtract<R1, R2> | R1​::​num * R2​::​den - | R1​::​den * R2​::​den |
| [ð](#tab:ratio.arithmetic-row-5) | R2​::​num * R1​::​den |  |
| [ð](#tab:ratio.arithmetic-row-6)<br>ratio_multiply<R1, R2> | R1​::​num * R2​::​num | R1​::​den * R2​::​den |
| [ð](#tab:ratio.arithmetic-row-7)<br>ratio_divide<R1, R2> | R1​::​num * R2​::​den | R1​::​den * R2​::​num |

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L7200)

[*Example [1](#example-1)*: 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 implementationsstatic_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*]
