Document Number: N3131=10-0121 Date: 2010-08-20 Author: Anthony WilliamsJust Software Solutions Ltd

# N3131: Compile-time rational arithmetic and overflow

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.

## Proposed Wording

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");