<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 948: ratio arithmetic tweak</title>
<meta property="og:title" content="Issue 948: ratio arithmetic tweak">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue948.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++11">C++11</a> status.</em></p>
<h3 id="948"><a href="lwg-defects.html#948">948</a>. <code>ratio</code> arithmetic tweak</h3>
<p><b>Section:</b> 21.5.4 <a href="https://wg21.link/ratio.arithmetic">[ratio.arithmetic]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2008-12-26 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#ratio.arithmetic">issues</a> in [ratio.arithmetic].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf">N2800</a>,
21.5.4 <a href="https://wg21.link/ratio.arithmetic">[ratio.arithmetic]</a> lacks a paragraph from the proposal
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm">N2661</a>:
</p>

<blockquote>
<p><b>ratio arithmetic [ratio.arithmetic]</b></p>

<p>
... If the implementation is unable to form the indicated <code>ratio</code> due to
overflow, a diagnostic shall be issued.
</p>
</blockquote>

<p>
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.
</p>

<p>
For example:
</p>

<blockquote>
<pre>
template &lt;class R1, class R2&gt; struct ratio_multiply {
  typedef <i>see below</i>} type; 
</pre>

<blockquote><p>
The nested typedef type shall be a synonym for <code>ratio&lt;T1, T2&gt;</code> where
<code>T1</code> has the value <code>R1::num * R2::num</code> and <code>T2</code> has the
value <code>R1::den * R2::den</code>.
</p></blockquote>

</blockquote>

<p>
Consider the case where <code>intmax_t</code> is a 64 bit 2's complement signed integer,
and we have:
</p>

<blockquote><pre>
typedef std::ratio&lt;0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF0&gt; R1;
typedef std::ratio&lt;8, 7&gt; R2;
typedef std::ratio_multiply&lt;R1, R2&gt;::type RT;
</pre></blockquote>

<p>
According to the present formulation the implementaiton will multiply
<code>0x7FFFFFFFFFFFFFFF * 8</code> which will result in an overflow and subsequently
require a diagnostic.
</p>

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

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

<p>
Example implmentation which accomplishes this:
</p>

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

<p><i>[
Post Summit:
]</i></p>


<blockquote><p>
Recommend Tentatively Ready.
</p></blockquote>




<p id="res-948"><b>Proposed resolution:</b></p>
<p>
Add a paragraph prior to p1 in 21.5.4 <a href="https://wg21.link/ratio.arithmetic">[ratio.arithmetic]</a>:
</p>

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





</body>
</html>
