This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

### 948. `ratio` arithmetic tweak

Section: 20.16.4 [ratio.arithmetic] Status: C++11 Submitter: Howard Hinnant Opened: 2008-12-26 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [ratio.arithmetic].

View all issues with C++11 status.

Discussion:

N2800, 20.16.4 [ratio.arithmetic] lacks a paragraph from the proposal N2661:

> ratio arithmetic [ratio.arithmetic]

> ... If the implementation is unable to form the indicated `ratio` due to overflow, a diagnostic shall be issued.

The lack of a diagnostic on compile-time overflow is a significant lack of functionality. This paragraph could be put back into the WP simply editorially. However in forming this issue I realized that we can do better than that. This paragraph should also allow alternative formulations which go to extra lengths to avoid overflow when possible. I.e. we should not mandate overflow when the implementation can avoid it.

For example:

>     template <class R1, class R2> struct ratio_multiply {
>       typedef see below} type;

> > The nested typedef type shall be a synonym for `ratio<T1, T2>` where `T1` has the value `R1::num * R2::num` and `T2` has the value `R1::den * R2::den`.

Consider the case where `intmax_t` is a 64 bit 2's complement signed integer, and we have:

>     typedef std::ratio<0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF0> R1;
>     typedef std::ratio<8, 7> R2;
>     typedef std::ratio_multiply<R1, R2>::type RT;

According to the present formulation the implementaiton will multiply `0x7FFFFFFFFFFFFFFF * 8` which will result in an overflow and subsequently require a diagnostic.

However if the implementation is first allowed to divde `0x7FFFFFFFFFFFFFFF` by `7` obtaining `0x1249249249249249 / 1` and divide `8` by `0x7FFFFFFFFFFFFFF0` obtaining `1 / 0x0FFFFFFFFFFFFFFE`, then the exact result can then be computed without overflow:

>     [0x7FFFFFFFFFFFFFFF/0x7FFFFFFFFFFFFFF0] * [8/7] = [0x1249249249249249/0x0FFFFFFFFFFFFFFE]

Example implmentation which accomplishes this:

>     template <class R1, class R2>
>     struct ratio_multiply
>     {
>     private:
>         typedef ratio<R1::num, R2::den> _R3;
>         typedef ratio<R2::num, R1::den> _R4;
>     public:
>         typedef ratio<__ll_mul<_R3::num, _R4::num>::value,
>                       __ll_mul<_R3::den, _R4::den>::value> type;
>     };

[ Post Summit: ]

> Recommend Tentatively Ready.

Proposed resolution:

Add a paragraph prior to p1 in 20.16.4 [ratio.arithmetic]:

> Implementations may use other algorithms to compute the indicated ratios to avoid overflow. If overflow occurs, a diagnostic shall be issued.