[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 such that U is the same as ratio​::​num andV is the same as ratio​::​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)
**Type** | **Value of X** | **Value of Y** | | --- | --- | --- | | [🔗](#tab:ratio.arithmetic-row-2)
ratio_add | R1​::​num * R2​::​den + | R1​::​den * R2​::​den | | [🔗](#tab:ratio.arithmetic-row-3) | R2​::​num * R1​::​den | | | [🔗](#tab:ratio.arithmetic-row-4)
ratio_subtract | R1​::​num * R2​::​den - | R1​::​den * R2​::​den | | [🔗](#tab:ratio.arithmetic-row-5) | R2​::​num * R1​::​den | | | [🔗](#tab:ratio.arithmetic-row-6)
ratio_multiply | R1​::​num * R2​::​num | R1​::​den * R2​::​den | | [🔗](#tab:ratio.arithmetic-row-7)
ratio_divide | 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, 6>>::num == 1, "1/3+1/6 == 1/2");static_assert(ratio_add, ratio<1, 6>>::den == 2, "1/3+1/6 == 1/2");static_assert(ratio_multiply, ratio<3, 2>>::num == 1, "1/3*3/2 == 1/2");static_assert(ratio_multiply, 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>>::num == 2, "1/MAX+1/MAX == 2/MAX");static_assert(ratio_add, ratio<1, INT_MAX>>::den == INT_MAX, "1/MAX+1/MAX == 2/MAX");static_assert(ratio_multiply, ratio>::num == 1, "1/MAX * MAX/2 == 1/2");static_assert(ratio_multiply, ratio>::den == 2, "1/MAX * MAX/2 == 1/2"); — *end example*]