Document Number: | N3131=10-0121 |

Date: | 2010-08-20 |

Author: | Anthony
Williams Just Software Solutions Ltd |

Comment GB 89 on the FCD (see N3102) raised the issue of how compile-time rational arithmetic should be done when the result is representable, but a simple application of arithmetic rules would result in overflow.

e.g. `ratio_multiply<ratio<INTMAX_MAX,2>,ratio<2,INTMAX_MAX>>`

can be
reduced to `ratio<1,1>`

, but the direct result
of `ratio<INTMAX_MAX*2,INTMAX_MAX*2>`

would result
in overflow.

The consensus in Rapperswil was to allow but not require the implementation to handle such overflow if the final result was representable.

Change the wording in 20.6.2 [ratio.arithmetic] as follows:

Implementations may use other algorithms to compute these values. If overﬂow occurs in the calculation of the result, the program is ill-formed. [Note: Implementations are encouraged to use alternative algorithms that avoid overflow in the calculation if the final result is representable. Such provision is conditionally supported. -- End Note]

template <class R1, class R2> using ratio_add =see below;The type

`ratio_add<R1, R2>`

shall be a synonym for`ratio<T1,T2>`

`ratio<U, V>`

such that`ratio<U,V>::num`

and`ratio<U,V>::den`

are the same as the corresponding members of`ratio<T1,T2>`

would be in the absence of arithmetic overflow where`T1`

has the value`R1::num * R2::den + R2::num * R1::den`

and`T2`

has the value`R1::den * R2::den`

. If the required values of`ratio<U,V>::num`

and`ratio<U,V>::den`

cannot be represented in`intmax_t`

then the program is illformed. Correct calculation of the result if either of`T1`

or`T2`

cannot be represented in`intmax_t`

is conditionally supported ([defns.cond.supp])template <class R1, class R2> using ratio_subtract =see below;The type

`ratio_subtract<R1, R2>`

shall be a synonym for`ratio<T1,T2>`

`ratio<U, V>`

such that`ratio<U,V>::num`

and`ratio<U,V>::den`

are the same as the corresponding members of`ratio<T1,T2>`

would be in the absence of arithmetic overflow where`T1`

has the value`R1::num * R2::den - R2::num * R1::den`

and`T2`

has the value`R1::den * R2::den`

. If the required values of`ratio<U,V>::num`

and`ratio<U,V>::den`

cannot be represented in`intmax_t`

then the program is illformed. Correct calculation of the result if either of`T1`

or`T2`

cannot be represented in`intmax_t`

is conditionally supported ([defns.cond.supp])template <class R1, class R2> using ratio_multiply =see below;The type

`ratio_multiply<R1, R2>`

shall be a synonym for`ratio<T1,T2>`

`ratio<U, V>`

such that`ratio<U,V>::num`

and`ratio<U,V>::den`

are the same as the corresponding members of`ratio<T1,T2>`

would be in the absence of arithmetic overflow where`T1`

has the value`R1::num * R2::num`

and`T2`

has the value`R1::den * R2::den`

. If the required values of`ratio<U,V>::num`

and`ratio<U,V>::den`

cannot be represented in`intmax_t`

then the program is illformed. Correct calculation of the result if either of`T1`

or`T2`

cannot be represented in`intmax_t`

is conditionally supported ([defns.cond.supp])template <class R1, class R2> using ratio_divide =see below;The type

`ratio_divide<R1, R2>`

shall be a synonym for`ratio<T1,T2>`

`ratio<U, V>`

such that`ratio<U,V>::num`

and`ratio<U,V>::den`

are the same as the corresponding members of`ratio<T1,T2>`

would be in the absence of arithmetic overflow where`T1`

has the value`R1::num * R2::den`

and`T2`

has the value`R1::den * R2::num`

. If the required values of`ratio<U,V>::num`

and`ratio<U,V>::den`

cannot be represented in`intmax_t`

then the program is illformed. Correct calculation of the result if either of`T1`

or`T2`

cannot be represented in`intmax_t`

is conditionally supported ([defns.cond.supp])[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_add<ratio<1,INTMAX_MAX>,ratio<1,INTMAX_MAX>>::num==2,"1/MAX+1/MAX==2/MAX"); // conditionally supported static_assert(ratio_add<ratio<1,INTMAX_MAX>,ratio<1,INTMAX_MAX>>::den==INTMAX_MAX,"1/MAX+1/MAX==2/MAX"); // conditionally supported 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"); static_assert(ratio_multiply<ratio<1,INTMAX_MAX>,ratio<INTMAX_MAX,2>>::num==1,"1/MAX * MAX/2==1/2"); // conditionally supported static_assert(ratio_multiply<ratio<1,INTMAX_MAX>,ratio<INTMAX_MAX,2>>::den==2,"1/MAX * MAX/2==1/2"); // conditionally supported--End Example]