<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>p0554r1</title>
  <style type="text/css">
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
  <style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(title);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  </style>
  <!--adapted from https://github.com/Thiht/markdown-viewer/blob/master/chrome/lib/sss/sss.css-->
  <style type="text/css">
  body {
      color: #333;
      font-family: 'Segoe UI', 'Lucida Grande', Helvetica, sans-serif;
      line-height: 1.5;
      margin: auto;
      max-width: 1000px;
  }
  
  h1, h2, h3, h4, h5, h6 {
      font-weight: normal;
      line-height: 1em;
      margin: 20px 0;
  }
  
  h1 {
      font-size: 2.25em;
  }
  
  h2 {
      font-size: 1.75em;
  }
  
  h3 {
      font-size: 1.5em;
  }
  
  h4, h5, h6 {
      font-size: 1.25em;
  }
  
  a {
      color: #08C;
      text-decoration: none;
  }
  
  a:hover, a:focus {
      text-decoration: underline;
  }
  
  a:visited {
      color: #058;
  }
  
  img {
      max-width: 100%;
  }
  
  li + li {
      margin-top: 3px;
  }
  
  dt {
      font-weight: bold;
  }
  
  code {
      background: #EEE;
      font-family: "Consolas", "Lucida Console", monospace;
      padding: 1px 5px;
  }
  
  pre {
      background: #EEE;
      padding: 5px 10px;
      white-space: pre-wrap;
  }
  
  pre code {
      padding: 0;
  }
  
  blockquote {
      border-left: 5px solid #EEE;
      margin: 0;
      padding: 0 10px;
  }
  
  table {
      border-collapse: collapse;
      width: 100%;
  }
  
  table + table {
      margin-top: 1em;
  }
  
  thead {
      background: #EEE;
      text-align: left;
  }
  
  th, td {
      border: 1px solid #EEE;
      padding: 5px 10px;
  }
  
  hr {
      background: #EEE;
      border: 0;
      height: 1px;
  }
  </style>
</head>
<body>
<p><strong>Document number</strong>: P0554R1<br />
<strong>Date</strong>: 2019-06-17<br />
<strong>Reply-to</strong>: John McFarlane, [wg21@john.mcfarlane.name](mailto:wg21@john.mcfarlane.name <strong>Audience</strong>: SG6, LEWGI</p>
<h1>Composition of Arithmetic Types</h1>
<h2>Contents</h2>
<ul>
<li><a href="#revisions">Revisions</a></li>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#goals">Goals</a>
<ul>
<li><a href="#goals-efficiency">Efficiency</a></li>
<li><a href="#goals-correctness">Correctness</a></li>
<li><a href="#goals-usability">Usability</a></li>
</ul></li>
<li><a href="#definitions">Definitions</a></li>
<li><a href="#prior_art">Prior Art</a>
<ul>
<li><a href="#prior_art-compositional">Compositional</a></li>
<li><a href="#prior_art-non_compositional">Non-Compositional</a></li>
</ul></li>
<li><a href="#componentization">Componentization</a>
<ul>
<li><a href="#componentization-overflow-detection">Example A: Overflow Detection</a></li>
<li><a href="#componentization-elasticity">Example B: Elasticity</a></li>
<li><a href="#componentization-scale">Example C: Scale</a></li>
</ul></li>
<li><a href="#composition">Composition</a>
<ul>
<li><a href="#composition-scaled_integer">Example A: Elastic Fixed-Point</a></li>
<li><a href="#composition-safe_integer">Example B: Safe Integer</a></li>
<li><a href="#composition-safe_scaled_integer">Example C: Safe Scaled Integer</a></li>
<li><a href="#elastic-deconstructed">Example D: Elastic Deconstructed</a></li>
</ul></li>
<li><a href="#advanced_topics">Advanced Topics</a>
<ul>
<li><a href="#advanced_topics-rounding">Rounding</a></li>
<li><a href="#advanced_topics-64_bit_limit">Breaking Through The 64-bit Barrier</a></li>
<li><a href="#advanced_topics-operator_overloads">Operator Overloads</a></li>
<li><a href="#advanced_topics-integral_constants">Integral Constants</a></li>
<li><a href="#advanced_topics-user_defined_literals">User-defined Literals</a></li>
</ul></li>
<li><a href="#acknowledgements">Acknowledgements</a></li>
<li><a href="#references">References</a></li>
</ul>
<h2><a id="revisions"></a>Revisions</h2>
<p>Revision 1 (This revision):</p>
<ul>
<li>Replaced <code>fixed_point</code> with <code>scaled_integer</code></li>
<li>Repalced <code>safe_integer</code> with <code>overflow_integer</code></li>
<li>Dropped explanation of fixed-point arithmetic</li>
<li>Dropped discussion of fixed-point division</li>
<li>Added section on construction of <code>elastic_integer</code> from <code>promotion_integer</code> and <code>narrow_integer</code></li>
<li>Removed several advanced topics: Leaky Abstractions, Generic Numeric Functions</li>
<li>Paragraph discussing P0880</li>
<li>Remove explicit reference in favor of inline hyperlinks</li>
<li>Countless grammar and formatting fixes</li>
</ul>
<h2><a id="introduction"></a>Introduction</h2>
<p>One of the goals of the Numerics TS is to add general-purpose arithmetic types to the library [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0101r0.html#Bounded">P0101</a>]. These types are to provide much needed safety and correctness features which are absent from fundamental types.</p>
<p>This paper puts the case for expressing those features as individual components which can then be composed into types with the desired feature set. This approach is referred to as the <em>compositional</em> approach and is characterized by class templates with <em>type</em> parameters:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb1-1" title="1"><span class="co">// approximate a real number by scaling an int32_t by 2^-16</span></a>
<a class="sourceLine" id="cb1-2" title="2"><span class="kw">using</span> f = scaled_integer&lt;<span class="dt">int32_t</span>, power&lt;-<span class="dv">16</span>, <span class="dv">2</span>&gt;&gt;;</a></code></pre></div>
<p>The compositional approach is contrasted with the <em>comprehensive</em> approach which aims to achieve similar goals using class templates with <em>non-type</em> parameters:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb2-1" title="1"><span class="co">// approximate a real number with 15 integer and 16 fractional digits</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="kw">using</span> f = scaled_integer&lt;<span class="dv">31</span>, power&lt;-<span class="dv">16</span>, <span class="dv">2</span>&gt;&gt;;</a></code></pre></div>
<h2><a id="goals"></a>Goals</h2>
<p>The design space of arithmetic types aims to satisfy goals which fall into three competing categories: <em>efficiency</em>, <em>correctness</em> and <em>usability</em>.</p>
<h3><a id="goals-efficiency"></a>Efficiency</h3>
<p>One aim of a library-based solution should be to maintain the efficiency of fundamental arithmetic types. Some run-time costs are inevitable additions to existing computation. All other run-time costs should be avoided in pursuit of zero-cost abstraction.</p>
<p>Further, a new wave of specialized hardware is reaching maturity in the form of heterogeneous processing units. These include the GPUs which provide the majority of computing power on modern PCs and mobile devices. The design and capabilities of these units is continually changing in ways which are difficult to predict. An interface which can easily be employed to harness these capabilities is highly valuable. And this may improve on the performance of existing fundamental types.</p>
<p>Over the past few decades, floating-point performance has largely caught up with integer performance. However, this has come at the cost of increased energy consumption. As performance per watt becomes the limiting factor for cloud and mobile platforms, so the economic impetus to use integers to approximate real numbers increases.</p>
<p>In summary, three efficiency-driven goals are:</p>
<ul>
<li>zero-cost abstraction over existing fundamental types;</li>
<li>extensibility and</li>
<li>increased applicability of integer hardware units.</li>
</ul>
<h3><a id="goals-correctness"></a>Correctness</h3>
<p>Native numeric types have a variety of characteristics that can make them difficult to use correctly. Among those within the scope of this document are:</p>
<p>Integers:</p>
<ul>
<li>operator overflow from: cast to float, shift left, multiplication, addition;</li>
<li>conversion overflow from: cast to narrower types and unsigned types;</li>
<li>undefined signed overflow vs modulo unsigned overflow;</li>
<li>surprising promotion rules;</li>
<li>divide-by-zero;</li>
<li>underflow/flushing;</li>
<li>variation across architectures;</li>
<li>endianness;</li>
<li>most negative value;</li>
<li>inconsistent/inaccurate rounding;</li>
<li>lack of fractional digits.</li>
</ul>
<p>Floating-point:</p>
<ul>
<li>precision varied by scale;</li>
<li>silent transition to special values;</li>
<li>special values causing loss of strict weak ordering;</li>
<li>lack of associativity and commutativity;</li>
<li>non-determinism;</li>
<li>divide-by-zero.</li>
</ul>
<p>One reason the list is shorter for floating-point is because of extra work it performs at run-time. But opportunities exist to address many of these items without run-time cost: increasingly, smarter numeric types can shift cost to the compiler. However, one problem is that the range of solutions is wide with no single solution to satisfy all use cases.</p>
<h3><a id="goals-usability"></a>Usability</h3>
<p>There are two overwhelming reasons why any new arithmetic types should emulate existing fundamental ones:</p>
<ol>
<li>They require little more than a rudimentary grasp of elementary algebra in order start learning.</li>
<li>They are a language feature with which almost all users have a familiarity (if not a mastery).</li>
</ol>
<p>It is true that many users complain that arithmetic types are hard to use. What they often mean is that they are hard to use <em>correctly</em>: the learning curve is mostly smooth but hits a bump whenever a <a href="#goals-correctness">Correctness</a> issue is encountered.</p>
<h2><a id="definitions"></a>Definitions</h2>
<p>A class is recognized as an arithmetic type if it possesses certain similarities with fundamental arithmetic types. In particular, it must have value semantics and arithmetic operators. It is often composed of simpler types such as fundamental arithmetic types. However, it is only said to have a compositional interface if the choice of type is a feature of its interface. Thus compositional interfaces tend to be part of class templates.</p>
<p>For example,</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb3-1" title="1"><span class="kw">template</span>&lt;<span class="kw">class</span> Rep&gt;</a>
<a class="sourceLine" id="cb3-2" title="2"><span class="kw">class</span> A {</a>
<a class="sourceLine" id="cb3-3" title="3">    Rep data;</a>
<a class="sourceLine" id="cb3-4" title="4">};</a>
<a class="sourceLine" id="cb3-5" title="5"></a>
<a class="sourceLine" id="cb3-6" title="6"><span class="kw">template</span>&lt;<span class="dt">int</span> Bits, <span class="dt">bool</span> Signed&gt;</a>
<a class="sourceLine" id="cb3-7" title="7"><span class="kw">class</span> B;</a>
<a class="sourceLine" id="cb3-8" title="8"></a>
<a class="sourceLine" id="cb3-9" title="9"><span class="kw">template</span>&lt;&gt;</a>
<a class="sourceLine" id="cb3-10" title="10"><span class="kw">class</span> B&lt;<span class="dv">32</span>, <span class="kw">false</span>&gt; {</a>
<a class="sourceLine" id="cb3-11" title="11">    <span class="dt">uint32_t</span> data;</a>
<a class="sourceLine" id="cb3-12" title="12">};</a>
<a class="sourceLine" id="cb3-13" title="13"></a>
<a class="sourceLine" id="cb3-14" title="14">A&lt;<span class="dt">uint32_t</span>&gt; a;</a>
<a class="sourceLine" id="cb3-15" title="15">B&lt;<span class="dv">32</span>, <span class="kw">false</span>&gt; b;</a></code></pre></div>
<p>both <code>a</code> and <code>b</code> are composed of the same data type but we only describe <code>a</code> as a compositional interface.</p>
<p>An important property of compositional interfaces are that they can be nested:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb4-1" title="1"><span class="kw">template</span>&lt;<span class="kw">class</span> T&gt;</a>
<a class="sourceLine" id="cb4-2" title="2"><span class="kw">class</span> C;</a>
<a class="sourceLine" id="cb4-3" title="3"></a>
<a class="sourceLine" id="cb4-4" title="4">C&lt;A&lt;T&gt;&gt; c;</a></code></pre></div>
<h2><a id="prior_art"></a>Prior Art</h2>
<h3><a id="prior_art-compositional"></a>Compositional</h3>
<p>Examples of existing types with a compositional interface include:</p>
<ul>
<li>integer types which test for overflow at run-time [<a href="https://cs.chromium.org/search/?q=file:src/base/numerics/safe_%5B%5E.%5D*%5C.h$&amp;sq=package:chromium&amp;type=cs">Chromium</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0228r0.pdf">P0228</a>, <a href="http://foonathan.net/doc/type_safe/">type_safe</a>];</li>
<li>fixed-point real number approximations [<a href="http://johnmcfarlane.github.io/scaled_integer/papers/p0037r3.html">P0037</a>, <a href="https://github.com/mizvekov/fp">fp</a>];</li>
<li>arbitrarily wide integers [<a href="http://www.boost.org/doc/libs/release/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html">Boost.Multiprecision</a>];</li>
<li>auto-widening integers [<a href="http://johnmcfarlane.github.io/scaled_integer/index.html#elastic">elastic_integer</a>);</li>
<li>complex numbers (<code>std::complex</code>) and</li>
<li>statically scaled time interval (<code>std::chrono::duration</code>).</li>
</ul>
<h3><a id="prior_art-non_compositional"></a>Non-Compositional</h3>
<p>Counter-examples include Lawrence Crowl's fixed-point paper [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0106r0.html">P0106</a>] which proposes a set of <em>comprehensive</em> class templates. These produce types which solve all or most of the integer correctness issues listed in section, <a href="#goals-correctness">Correctness</a>.</p>
<p>Other counter-examples include:</p>
<ul>
<li>arbitrarily wide integers [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0104r0.html">P0104</a>, <a href="https://cerevra.github.io/int/">wide_int</a>, <a href="http://www.boost.org/doc/libs/release/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html">Boost.Multiprecision</a>] and</li>
<li>an integer type which detects overflow conditions [<a href="https://bitbucket.org/davidstone/bounded_integer">bounded::integer</a>].</li>
</ul>
<p>(Note that [<a href="http://www.boost.org/doc/libs/release/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html">Boost.Multiprecision</a>] earns a place on both lists as it uses both compositional and non-compositional techniques.)</p>
<h2><a id="componentization"></a>Componentization</h2>
<p>This section introduces several examples of arithmetic components and explores how they behave when specialized using fundamental types. Each is compared to equivalent comprehensive classes and functionality from [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0106r0.html">P0106</a>].</p>
<h3><a id="componentization-overflow-detection"></a>Example A: Overflow Detection</h3>
<p>There are many examples of libraries which aim to add run-time error detection to integers. These are useful for addressing:</p>
<ul>
<li>uninitialized data;</li>
<li>divide by zero;</li>
<li>overflow due to arithmetic operations;</li>
<li>overflow due to cast from wider integer;</li>
<li>overflow due to cast from floating-point type and</li>
<li>most negative value.</li>
</ul>
<p>The <code>integral</code> (signed) and <code>cardinal</code> (unsigned) class templates from [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0106r0.html">P0106</a>] perform such a role using non-type template parameters, e.g.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb5-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> Crng, overflow Covf = overflow::exception&gt;</a>
<a class="sourceLine" id="cb5-2" title="2"><span class="kw">class</span> integral;</a></code></pre></div>
<p>where <code>Crng</code> specifies the range of the value in bits and <code>overflow</code> is an enum which specifies what happens if overflow is detected. The values of <code>overflow</code> include:</p>
<ul>
<li><code>undefined</code> - much like signed integer overflow behavior;</li>
<li><code>abort</code> - forces program termination;</li>
<li><code>exception</code> - throws an exception;</li>
<li><code>saturate</code> - limits the value to the maximum/minimum allowed by the range.</li>
</ul>
<p>The complete list of values is found in [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0105r0.html#OverMode">P0105</a>] and covers a wide range of use cases. However, it is necessarily finite. If any new mode is desired, it must wait on a revision to the standard.</p>
<p>The compositional equivalent might look like</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb6-1" title="1"><span class="kw">template</span>&lt;<span class="kw">class</span> Rep = <span class="dt">int</span>, <span class="kw">class</span> Tag = contract_overflow_tag&gt;</a>
<a class="sourceLine" id="cb6-2" title="2"><span class="kw">class</span> overflow_integer {</a>
<a class="sourceLine" id="cb6-3" title="3">    Rep <span class="va">rep_</span>;</a>
<a class="sourceLine" id="cb6-4" title="4">  <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb6-5" title="5">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb6-6" title="6">};</a></code></pre></div>
<p>where <code>Tag</code> is an alternative to P0106's <code>overflow</code> enumeration and provides a choice of behaviors to exhibit when overflow is detected. Choices may include:</p>
<ul>
<li><code>contract_overflow_tag</code> - makes out-of-range a pre/post-condition violation;</li>
<li><code>saturate_overflow_tag</code> - clamps out-of-range values to minimum/maximum value;</li>
<li><code>modulo_overflow_tag</code> - wraps out-of-range value a la unsigned and</li>
<li><code>sticky_overflow_tag</code> - saturates and stays saturated (like IEEE 754).</li>
</ul>
<p>In practice, all of these integer types: <code>overflow_integer</code>, <code>integral</code> and <code>cardinal</code> behave similarly to fundamental integers <em>until</em> overflow occurs:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb7-1" title="1">overflow_integer&lt;<span class="dt">uint8_t</span>&gt; n{<span class="dv">255</span>};  <span class="co">// interface hints that n resembles uint8_t</span></a>
<a class="sourceLine" id="cb7-2" title="2">++ n;  <span class="co">// but when its range is exceeded, an exception is thrown</span></a>
<a class="sourceLine" id="cb7-3" title="3"></a>
<a class="sourceLine" id="cb7-4" title="4">overflow_integer&lt;<span class="dt">int</span>, saturate_overflow_tag&gt; i = <span class="fl">1e100</span>;  <span class="co">// i == INT_MAX</span></a></code></pre></div>
<p>Crucially, <code>overflow_integer&lt;T&gt;</code> gives the user a strong hint that they can expect similar characteristics to <code>T</code>. If the user is familiar with <code>int</code> and chooses it to specialize <code>overflow_integer</code>, they should have a good idea of how it will behave.</p>
<p>But the most remarkable safety feature of [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0106r0.html">P0106</a>]'s types is not supported by <code>overflow_integer</code> at all...</p>
<h3><a id="componentization-elasticity"></a>Example B: Elasticity</h3>
<p>Elasticity is the ability to expand range in order to contain a growing value. For instance, when two 8-bit numbers are summed, the result cannot exceed 9 bits. And when two 20-bit numbers are multiplied, the result cannot exceed 40 bits. Thus, an elastic type tracks the exact number of bits used and returns suitably widened results from binary arithmetic operations. This eliminates a common class of overflow errors without the need for run-time checks.</p>
<p>[<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0106r0.html">P0106</a>]'s integer types achieve elasticity by adjusting range:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb8-1" title="1">integral&lt;<span class="dv">4</span>&gt; n = <span class="dv">15</span>;  <span class="co">// 4-digit signed integer</span></a>
<a class="sourceLine" id="cb8-2" title="2"><span class="kw">auto</span> nn = n * n;  <span class="co">// 8-digit signed integer</span></a></code></pre></div>
<p>Consider an equivalent compositional type, <code>elastic_integer</code>:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> Digits, <span class="kw">class</span> Narrowest = <span class="dt">int</span>&gt;</a>
<a class="sourceLine" id="cb9-2" title="2"><span class="kw">class</span> elastic_integer;</a></code></pre></div>
<p><code>Digits</code> is equivalent to <code>Crng</code> - the number of digits of capacity.</p>
<p><code>Narrowest</code> serves a similar purpose to the <code>Rep</code> parameter of <a href="#componentization-overflow-detection"><code>overflow_integer</code></a>. However, it is not guaranteed to be the type of <code>elastic_integer</code>'s member variable. For example,</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb10-1" title="1">elastic_integer&lt;<span class="dv">10</span>, <span class="dt">int16_t</span>&gt; n;</a></code></pre></div>
<p>uses an <code>int16_t</code> to store a value in the range, [-1023..1023]. To avoid overflow, <code>elastic_integer</code>'s binary arithmetic operators 'stretch' the value of <code>Digits</code>:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb11-1" title="1"><span class="kw">auto</span> nn = n * n;  <span class="co">// elastic_integer&lt;20, int16_t&gt;</span></a></code></pre></div>
<p>As <code>int16_t</code> cannot store a 20-bit value, a wider type is used. <code>Narrowest</code> might seem superfluous - given <code>Digits</code> can override the type's width. However, it serves two important purposes.</p>
<p>Firstly, storage requirements vary depending on use case. When serializing to file, compactness may be preferable, in which case, <code>int8_t</code> or <code>uint8_t</code> is appropriate. In most other situations, performance is paramount and <code>int</code> makes a better choice. It is hoped that <code>Narrowest</code> makes the most sense to users who are already familiar with this trade-off.</p>
<p>Secondly, <code>Narrowest</code> determines the set of types from which a member variable will be chosen. If <code>int8_t</code> is specified, then <code>int16_t</code>, <code>int32_t</code> and <code>int64_t</code> will be used as width dictates whereas <code>uint8_t</code> will expand to <code>uint16_t</code>, <code>uint32_t</code> and <code>uint64_t</code>.</p>
<p>There is nothing to prevent <code>Narrowest</code> being a custom arithmetic type of the user's choosing. One stipulation, however, is that <code>elastic_integer</code> is able to choose a wider type as required. The details of how this is achieved are covered in [<a href="http://wg21.link/p1751">P1751</a>].</p>
<h3><a id="componentization-scale"></a>Example C: Scale</h3>
<p>Fixed-point numbers have always held certain efficiency and correctness advantages over floating-point types. Modern language features mean that they are also much simpler to work with.</p>
<p>[<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0106r0.html">P0106</a>]'s <code>integral</code> and <code>cardinal</code> class templates are complemented by fixed-point templates, <code>negatable</code> and <code>nonnegative</code> respectively, e.g.:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb12-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> Crng, <span class="dt">int</span> Crsl, round Crnd = rounding::tie_to_odd, overflow Covf = overflow::exception&gt;</a>
<a class="sourceLine" id="cb12-2" title="2"><span class="kw">class</span> negatable;</a></code></pre></div>
<p>They come with two additional template parameters. <code>Crsl</code> specifies resolution. For example,</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb13-1" title="1">nonnegative&lt;<span class="dv">8</span>, -<span class="dv">4</span>&gt; n;</a></code></pre></div>
<p>instantiates a variable with 8 integer bits and 4 fractional bits. Its maximum, minimum and lowest values are <code>255.9375</code>, <code>0.0625</code> and <code>0</code> respectively.</p>
<p><code>Crnd</code> specifies the rounding mode as described in [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0105r0.html">P0105</a>]. The default, <code>rounding::tie_to_odd</code>, represents the best information preservation. The list of alternatives supplied by <code>rounding</code> is extensive but - just as with <code>overflow</code> - it is finite.</p>
<p>An alternative, compositional fixed-point solution is, <code>scaled_integer</code>, proposed in [<a href="http://wg21.link/p0037">P0037</a>]:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb14-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> Exponent = <span class="dv">0</span>, <span class="dt">int</span> Radix = <span class="dv">2</span>&gt;</a>
<a class="sourceLine" id="cb14-2" title="2"><span class="kw">class</span> power;</a>
<a class="sourceLine" id="cb14-3" title="3"></a>
<a class="sourceLine" id="cb14-4" title="4"><span class="kw">template</span>&lt;<span class="kw">class</span> Rep = <span class="dt">int</span>, <span class="kw">class</span> Scale = power&lt;&gt;&gt;</a>
<a class="sourceLine" id="cb14-5" title="5"><span class="kw">class</span> scaled_integer;</a></code></pre></div>
<p><code>power</code> is a helper type -- rather like a parameterised tag type. It represents a compile-time scaling factor.</p>
<p><code>Exponent</code> governs scaling in much the same way as the exponent of an IEEE 754 floating-point type. It is equivalent to <code>Crsl</code>.</p>
<p><code>Radix</code> can be changed to <code>10</code> in order to produce a decimal fixed-point type suitable for financial -- and other -- applications where accurate representation of decimal fractions is essential.</p>
<p>Aside from its compositional interface the most obvious difference between <code>scaled_integer</code> and <code>negatable</code> is that <code>scaled_integer</code> does not handle rounding. Rounding and scaling are orthogonal concerns. It should be possible to devise a <code>rounding_integer</code> component which handles rounding separately. See <a href="#advanced_topics-rounding">Rounding</a> for further discussion.</p>
<h2><a id="composition"></a>Composition</h2>
<p>In the previous section, three arithmetic components are introduced. Each component can be instantiated using fundamental integer types such as <code>int</code>, resulting in incremental enhancements to <code>int</code>. This section illustrates ways in which nested composition can combine these enhancements.</p>
<h3><a id="composition-scaled_integer"></a>Example A: Elastic Fixed-Point</h3>
<p>Fixed-point arithmetic is especially susceptible to overflow. Integers typically represent small quantities whereas fixed-point values often saturate their range:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb15-1" title="1"><span class="dt">int32_t</span> toes = <span class="dv">10</span>;  <span class="co">// uses 4 bits</span></a>
<a class="sourceLine" id="cb15-2" title="2">scaled_integer&lt;<span class="dt">int32_t</span>, power&lt;-<span class="dv">30</span>&gt;&gt; probability = <span class="fl">0.9</span>;  <span class="co">// uses 30 bits</span></a></code></pre></div>
<p>This means that hand-rolled fixed-point arithmetic involves keeping track of - not only scale but also - range:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb16-1" title="1"><span class="co">// square a floating-point value with 16 bits of fractional precision</span></a>
<a class="sourceLine" id="cb16-2" title="2"><span class="dt">float</span> square(<span class="dt">float</span> input) {</a>
<a class="sourceLine" id="cb16-3" title="3">    <span class="kw">auto</span> fixed = <span class="kw">static_cast</span>&lt;<span class="dt">int32_t</span>&gt;{input * <span class="fl">65536.</span><span class="bu">f</span>};</a>
<a class="sourceLine" id="cb16-4" title="4">    <span class="kw">auto</span> prod = <span class="dt">int64_t</span>{fixed} * fixed; <span class="co">// result must be widened</span></a>
<a class="sourceLine" id="cb16-5" title="5">    <span class="cf">return</span> prod / <span class="fl">4294967296.</span><span class="bu">f</span>; <span class="co">// gotcha: scale has changed</span></a>
<a class="sourceLine" id="cb16-6" title="6">}</a></code></pre></div>
<p>This error-prone work can be automated with a template composed of <code>scaled_integer</code> and <code>elastic_integer</code>:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb17-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> Digits, <span class="dt">int</span> Exponent, <span class="kw">class</span> Narrowest = <span class="dt">int</span>&gt;</a>
<a class="sourceLine" id="cb17-2" title="2"><span class="kw">using</span> elastic_scaled_integer =</a>
<a class="sourceLine" id="cb17-3" title="3">        scaled_integer&lt;</a>
<a class="sourceLine" id="cb17-4" title="4">            elastic_integer&lt;Digits, Narrowest&gt;, </a>
<a class="sourceLine" id="cb17-5" title="5">            power&lt;Exponent&gt;&gt;;</a></code></pre></div>
<p>The same <code>square</code> function is now clearer:</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb18-1" title="1"><span class="dt">float</span> square(<span class="dt">float</span> input) {</a>
<a class="sourceLine" id="cb18-2" title="2">    <span class="kw">auto</span> fixed = elastic_scaled_integer&lt;<span class="dv">31</span>, -<span class="dv">16</span>&gt;{input};</a>
<a class="sourceLine" id="cb18-3" title="3">    <span class="kw">auto</span> prod = fixed * fixed;</a>
<a class="sourceLine" id="cb18-4" title="4">    <span class="cf">return</span> <span class="kw">static_cast</span>&lt;<span class="dt">float</span>&gt;(prod);</a>
<a class="sourceLine" id="cb18-5" title="5">}</a></code></pre></div>
<p>In both cases, a modern optimizing compiler produces the same x86-64 assembler instructions [<a href="https://godbolt.org/g/mWTmlv">godbolt</a>], e.g.:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode asm"><code class="sourceCode fasm"><a class="sourceLine" id="cb19-1" title="1">square(float):</a>
<a class="sourceLine" id="cb19-2" title="2">        <span class="bu">mulss</span>   <span class="kw">xmm0</span>, <span class="dt">DWORD</span> <span class="dt">PTR</span> .LC0[rip]</a>
<a class="sourceLine" id="cb19-3" title="3">        <span class="bu">cvttss2si</span>       <span class="kw">eax</span>, <span class="kw">xmm0</span></a>
<a class="sourceLine" id="cb19-4" title="4">        <span class="bu">pxor</span>    <span class="kw">xmm0</span>, <span class="kw">xmm0</span></a>
<a class="sourceLine" id="cb19-5" title="5">        <span class="bu">cdqe</span></a>
<a class="sourceLine" id="cb19-6" title="6">        <span class="bu">imul</span>    <span class="kw">rax</span>, <span class="kw">rax</span></a>
<a class="sourceLine" id="cb19-7" title="7">        cvtsi2ssq       <span class="kw">xmm0</span>, <span class="kw">rax</span></a>
<a class="sourceLine" id="cb19-8" title="8">        <span class="bu">mulss</span>   <span class="kw">xmm0</span>, <span class="dt">DWORD</span> <span class="dt">PTR</span> .LC1[rip]</a>
<a class="sourceLine" id="cb19-9" title="9">        <span class="bu">ret</span></a>
<a class="sourceLine" id="cb19-10" title="10"><span class="fu">.LC0:</span></a>
<a class="sourceLine" id="cb19-11" title="11">        .long   <span class="dv">1199570944</span></a>
<a class="sourceLine" id="cb19-12" title="12"><span class="fu">.LC1:</span></a>
<a class="sourceLine" id="cb19-13" title="13">        .long   <span class="dv">796917760</span></a></code></pre></div>
<p>Multiplication is the easiest arithmetic operator to deal with. Addition and subtraction require that both operands be scaled to the same amount before addition. Division is an open topic explored in [<a href="http://wg21.link/p1368r1">P1368</a>].</p>
<h3><a id="composition-safe_integer"></a>Example B: Safe Integer</h3>
<p>With the correct set of components, it's possible to instantiate an integer type which has excellent correctness and usability characteristics. The following composite is practically overflow-proof and performs minimal run-time checks:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb20-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> IntegerDigits, <span class="kw">class</span> Rep = <span class="dt">int</span>, <span class="kw">class</span> OverflowTag = contract_overflow_tag&gt;</a>
<a class="sourceLine" id="cb20-2" title="2"><span class="kw">using</span> safe_integer = </a>
<a class="sourceLine" id="cb20-3" title="3">        overflow_integer&lt;</a>
<a class="sourceLine" id="cb20-4" title="4">            elastic_integer&lt;IntegerDigits, Rep&gt;,</a>
<a class="sourceLine" id="cb20-5" title="5">            <span class="kw">class</span> OverflowTag&gt;;</a></code></pre></div>
<p>The order of the nesting is crucial in ensuring that checks are minimized. This is because there is overlap in the concerns of the two components: <code>overflow_integer</code> traps binary arithmetic overflow whereas <code>elastic_integer</code> avoids it. Detection of something that isn't going to happen is a needless cost. By being aware of the types involved in operations, <code>overflow_integer</code> can be more selective about checks.</p>
<p>Consider <code>overflow_integer</code>'s multiplication operator:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb21-1" title="1"><span class="kw">template</span>&lt;<span class="kw">class</span> RepA, <span class="kw">class</span> RepB, <span class="kw">class</span> OverflowTag&gt;</a>
<a class="sourceLine" id="cb21-2" title="2"><span class="kw">auto</span> <span class="kw">operator</span>*(overflow_integer&lt;RepA, OverflowTag&gt; <span class="at">const</span> &amp; a,</a>
<a class="sourceLine" id="cb21-3" title="3">               overflow_integer&lt;RepB, OverflowTag&gt; <span class="at">const</span> &amp; b)</a>
<a class="sourceLine" id="cb21-4" title="4">{</a>
<a class="sourceLine" id="cb21-5" title="5">    <span class="kw">using</span> <span class="dt">result_type</span> = <span class="kw">decltype</span>(a.data() * b.data());</a>
<a class="sourceLine" id="cb21-6" title="6">    <span class="kw">constexpr</span> <span class="kw">auto</span> digits_a = <span class="bu">std::</span>numeric_limits&lt;RepA&gt;::digits;</a>
<a class="sourceLine" id="cb21-7" title="7">    <span class="kw">constexpr</span> <span class="kw">auto</span> digits_b = <span class="bu">std::</span>numeric_limits&lt;RepB&gt;::digits;</a>
<a class="sourceLine" id="cb21-8" title="8">    <span class="kw">constexpr</span> <span class="kw">auto</span> digits_result = <span class="bu">std::</span>numeric_limits&lt;<span class="dt">result_type</span>&gt;::digits;</a>
<a class="sourceLine" id="cb21-9" title="9">    <span class="cf">if</span> <span class="kw">constexpr</span> (digits_a + digits_b &gt;= digits_result) {</a>
<a class="sourceLine" id="cb21-10" title="10">        <span class="co">// perform overflow test</span></a>
<a class="sourceLine" id="cb21-11" title="11">    }</a>
<a class="sourceLine" id="cb21-12" title="12">    <span class="cf">else</span> {</a>
<a class="sourceLine" id="cb21-13" title="13">        <span class="co">// skip overflow test</span></a>
<a class="sourceLine" id="cb21-14" title="14">    }</a>
<a class="sourceLine" id="cb21-15" title="15">    <span class="cf">return</span> a.data() * b.data();</a>
<a class="sourceLine" id="cb21-16" title="16">}</a></code></pre></div>
<p>We see that unnecessary run-time checks are eliminated.</p>
<p>This holds - not only for <code>elastic_integer</code> but also - for fundamental types that are implicitly promoted:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb22-1" title="1">overflow_integer&lt;<span class="dt">int8_t</span>&gt; a, b;</a>
<a class="sourceLine" id="cb22-2" title="2"><span class="kw">auto</span> c = a * b;  <span class="co">// c is overflow_integer&lt;int&gt;; no need for run-time check</span></a></code></pre></div>
<h3><a id="composition-safe_scaled_integer"></a>Example C: Safe Scaled Integer</h3>
<p>This sub-section combines all three of <code>scaled_integer</code>, <code>overflow_integer</code> and <code>elastic_integer</code> to make an even more feature-rich, deeply-nested composite:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb23-1" title="1"><span class="kw">template</span>&lt;</a>
<a class="sourceLine" id="cb23-2" title="2">    <span class="dt">int</span> Digits,</a>
<a class="sourceLine" id="cb23-3" title="3">    <span class="dt">int</span> Exponent = <span class="dv">0</span>,</a>
<a class="sourceLine" id="cb23-4" title="4">    <span class="kw">class</span> Narrowest = <span class="dt">int</span>,</a>
<a class="sourceLine" id="cb23-5" title="5">    <span class="kw">class</span> OverflowTag = contract_overflow_tag&gt;</a>
<a class="sourceLine" id="cb23-6" title="6"><span class="kw">using</span> safe_scaled_integer = </a>
<a class="sourceLine" id="cb23-7" title="7">        scaled_integer&lt;</a>
<a class="sourceLine" id="cb23-8" title="8">            overflow_integer&lt;</a>
<a class="sourceLine" id="cb23-9" title="9">                elastic_integer&lt;</a>
<a class="sourceLine" id="cb23-10" title="10">                    Digits, </a>
<a class="sourceLine" id="cb23-11" title="11">                    Narrowest&gt;,</a>
<a class="sourceLine" id="cb23-12" title="12">                OverflowTag&gt;, </a>
<a class="sourceLine" id="cb23-13" title="13">            power&lt;Exponent&gt;&gt;;</a></code></pre></div>
<p>This type is a run-time-efficient, overflow-proof real number approximation:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb24-1" title="1">safe_scaled_integer&lt;<span class="dv">5</span>, <span class="dv">0</span>&gt; a = <span class="dv">30</span>;</a>
<a class="sourceLine" id="cb24-2" title="2">safe_scaled_integer&lt;<span class="dv">2</span>, <span class="dv">0</span>&gt; b = <span class="dv">2</span>;</a>
<a class="sourceLine" id="cb24-3" title="3"><span class="kw">auto</span> c = a * b; <span class="co">// safe_scaled_integer&lt;7, 0&gt;{60}</span></a>
<a class="sourceLine" id="cb24-4" title="4"><span class="kw">auto</span> d = a + b; <span class="co">// safe_scaled_integer&lt;6, 0&gt;{32}</span></a>
<a class="sourceLine" id="cb24-5" title="5"><span class="kw">auto</span> e = c / d; <span class="co">// safe_scaled_integer&lt;7, 6&gt;{1.875}</span></a>
<a class="sourceLine" id="cb24-6" title="6">a -= <span class="dv">10</span>;    <span class="co">// safe_scaled_integer&lt;5&gt;{20}</span></a>
<a class="sourceLine" id="cb24-7" title="7">++ b;   <span class="co">// safe_scaled_integer&lt;2&gt;{3}</span></a>
<a class="sourceLine" id="cb24-8" title="8">++ b;   <span class="co">// contract violation!</span></a></code></pre></div>
<p>The above is an abstraction over the following code...</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb25-1" title="1"><span class="dt">int</span> a = limit&lt;overflow::exception&gt;(-<span class="dv">32</span>, <span class="dv">31</span>, <span class="dv">30</span>);</a>
<a class="sourceLine" id="cb25-2" title="2"><span class="dt">int</span> b = limit&lt;overflow::exception&gt;(-<span class="dv">4</span>, <span class="dv">3</span>, <span class="dv">2</span>);</a>
<a class="sourceLine" id="cb25-3" title="3"><span class="dt">int</span> c = a * b;</a>
<a class="sourceLine" id="cb25-4" title="4"><span class="dt">int</span> d = a + b;</a>
<a class="sourceLine" id="cb25-5" title="5"><span class="dt">int</span> e = (c * (<span class="dv">1</span> &lt;&lt; <span class="dv">6</span>)) / d;</a>
<a class="sourceLine" id="cb25-6" title="6">a = limit&lt;overflow::exception&gt;(-<span class="dv">32</span>, <span class="dv">31</span>, a - <span class="dv">10</span>);</a>
<a class="sourceLine" id="cb25-7" title="7">b = limit&lt;overflow::exception&gt;(-<span class="dv">4</span>, <span class="dv">3</span>, b + <span class="dv">1</span>);</a>
<a class="sourceLine" id="cb25-8" title="8">b = limit&lt;overflow::exception&gt;(-<span class="dv">4</span>, <span class="dv">3</span>, b + <span class="dv">1</span>);</a></code></pre></div>
<p>...where <code>limit</code> is a function template which handles overflow at run-time. (A similar facility is detailed in [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0105r0.html#OverFunctions">P0105</a>].)</p>
<h3><a id="elastic-deconstructed"></a>Example D: Elastic Deconstructed</h3>
<p>Components themselves can often be further broken down into constituent parts. An example is how <code>elastic_integer</code> can be built up as an alias of two other types, <code>promotion_integer</code> and <code>narrow_integer</code>:</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb26-1" title="1"><span class="kw">template</span>&lt;<span class="kw">class</span> Rep = <span class="dt">int</span>&gt;</a>
<a class="sourceLine" id="cb26-2" title="2">promotion_integer;</a>
<a class="sourceLine" id="cb26-3" title="3"></a>
<a class="sourceLine" id="cb26-4" title="4"><span class="kw">template</span>&lt;<span class="dt">int</span> MinDigits, <span class="kw">class</span> Narrowest = <span class="dt">int</span>&gt;</a>
<a class="sourceLine" id="cb26-5" title="5">narrow_integer;</a></code></pre></div>
<p>Just like <code>elastic_integer</code>, <code>promotion_integer</code> returns widened results from arithmetic operations in order to avoid overflow. But unlike <code>elastic_integer</code>, it doesn't remember the number of digits being used by its <code>Rep</code> value.</p>
<p>Conversely, <code>narrow_integer</code> remembers the number of digits being used by its <code>Rep</code> value, but it doesn't return widened results from arithmetic operations.</p>
<p>Clearly, these types were made for each other. Together, they make <code>elastic_integer</code> as an alias:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb27-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> MinDigits, <span class="kw">class</span> = Narrowest&gt;</a>
<a class="sourceLine" id="cb27-2" title="2"><span class="kw">using</span> elastic_integer = promotion_integer&lt;narrow_integer&lt;MinDigits, Narrowest&gt;&gt;;</a></code></pre></div>
<p>Why bother to break <code>elastic_integer</code> down like this? Well, unlike fundamental integer types, many numeric types track their own digits. They don't need <code>elastic_integer</code>'s <code>MinDigits</code> parameter. In fact, it confuses matters quite a bit.</p>
<p>Many statically-allocated 'bignum' types track their width as part of their type. One such example is the <code>wide_integer</code> type from [<a href="http://wg21.link/p0539r3">P0539</a>]:</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb28-1" title="1"><span class="kw">template</span>&lt;<span class="dt">size_t</span> Bits, <span class="kw">typename</span> S&gt;</a>
<a class="sourceLine" id="cb28-2" title="2"><span class="kw">class</span> wide_integer;</a></code></pre></div>
<p>The combination of <code>promotion_integer</code> and <code>wide_integer</code> works well but <code>elastic_integer</code> or <code>narrow_integer</code> with their additional <code>MinDigits</code> parameter would only get in the way:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb29-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> MinDigits, <span class="kw">typename</span> S = <span class="dt">signed</span>&gt;</a>
<a class="sourceLine" id="cb29-2" title="2"><span class="kw">using</span> wide_elastic_integer = promotion_integer&lt;wide_integer&lt;MinDigits, S&gt;&gt;;</a></code></pre></div>
<p>This composite, <code>wide_elastic_integer</code>, is a powerful abstraction for safely storing large numbers and operating on them with less chance of overflow.</p>
<h2><a id="advanced_topics"></a>Advanced Topics</h2>
<p>It is not claimed that a complete set of solutions has been presented so far. However, it is hoped that much of the appeal of the compositional approach is apparent. This section is a grab bag of topics of relevance to the types of a numerics TS. These topics are discussed with the compositional approach in mind.</p>
<h3><a id="advanced_topics-rounding"></a>Rounding</h3>
<p>[<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0106r0.html">P0106</a>]'s <code>negatable</code> and <code>nonnegative</code> offer a choice of rounding modes whereas their integer equivalents do not. However, rounding is orthogonal to real number approximation and is best embodied in its own component, <code>rounding_integer</code>:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb30-1" title="1"><span class="kw">template</span>&lt;<span class="kw">class</span> Rep, <span class="kw">class</span> RoundingTag = nearest_rounding_mode&gt;</a>
<a class="sourceLine" id="cb30-2" title="2"><span class="kw">class</span> rounding_integer;</a></code></pre></div>
<h3><a id="advanced_topics-64_bit_limit"></a>Breaking Through The 64-bit Barrier</h3>
<p>Another component which has barely been mentioned so far is <code>wide_integer</code>. Multiplication of <code>elastic_integer</code> results in double-wide types. This quickly hits limits:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb31-1" title="1">elastic_integer&lt;&gt; n;  <span class="co">// typically 31 digits</span></a>
<a class="sourceLine" id="cb31-2" title="2"><span class="kw">auto</span> n2 = n * n;    <span class="co">// 62 digits</span></a>
<a class="sourceLine" id="cb31-3" title="3"><span class="kw">auto</span> n4 = n2 * n2;  <span class="co">// 124 digits</span></a></code></pre></div>
<p>There is no standard facility to represent values greater than 64 bits with fundamental types. This limit routinely causes expressions to fail compilation. For this reason, either a <code>wide_integer</code> is needed or <code>elastic_integer</code> must handle multi-word values. Papers, [<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0104r0.html">P0104</a>] and [<a href="https://cerevra.github.io/int/">wide_int</a>] both explore this topic.</p>
<h3><a id="advanced_topics-operator_overloads"></a>Operator Overloads</h3>
<p>This paper is also light on details regarding operator overloads. However, they play a vital role in providing the semantics of arithmetic types. It is a non-trivial undertaking to support a complete set of operators for a single interface yet the compositional approach requires multiple interfaces. Thus the number of operator overloads (and special functions) is considerable. Any language features which can reduce this boilerplate are welcome.</p>
<p>Many functions are lightweight wrappers over a <code>Rep</code> type. An example of a feature which could reduce such boilerplate is the spaceship operator.</p>
<p>Another proposal which aims to reduce the number of operators that need to be written is <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0880r2.html">P0880</a>. Unfortunately, it is of limited use as it requires homogenous operand types for binary operators and many of the most interesting types, notably <code>scaled_integer</code> and <code>promotion_integer</code> insist on heterogeneous operands.</p>
<h3><a id="advanced_topics-integral_constants"></a>Integral Constants</h3>
<p>Integral constants are very useful for picking the best type for certain tasks.</p>
<p>Compound operation on <code>elastic_integer</code> leads quickly to overflow. This is not helped when the initial input to the expression is already 31 digits in width due to it being initialized by an <code>int</code> value:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb32-1" title="1">elastic_integer&lt;<span class="dv">2</span>&gt; x = <span class="dv">3</span>;   <span class="co">// x uses 2 digits</span></a>
<a class="sourceLine" id="cb32-2" title="2"><span class="kw">auto</span> y = x * <span class="dv">2</span>; <span class="co">// suddenly result uses over 33 digits to store value 6</span></a></code></pre></div>
<p>If the value (and therefore the range) is known at compile time, a much narrower result type can be generated:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb33-1" title="1"><span class="kw">auto</span> z = x * <span class="bu">std::</span>integral_constant&lt;<span class="dt">int</span>, <span class="dv">2</span>&gt;; <span class="co">// only 4 digits used in result</span></a></code></pre></div>
<p>Binary bit shift operations are a major benefactor of <code>integral_constant</code> operands. In this example</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb34-1" title="1"><span class="kw">auto</span> a = scaled_integer&lt;<span class="dt">int</span>, power&lt;<span class="dv">0</span>&gt;&gt;{<span class="dv">1</span>};</a>
<a class="sourceLine" id="cb34-2" title="2"><span class="kw">auto</span> b = a &lt;&lt; <span class="bu">std::</span>integral_constant&lt;<span class="dt">int</span>, <span class="dv">10</span>&gt;;   <span class="co">// scaled_integer&lt;int, power&lt;10&gt;&gt;{1024}</span></a></code></pre></div>
<p>both <code>a</code> and <code>b</code> store the same underlying value. No actual shift is required.</p>
<p>Another technique which uses compile-time constants to avoid run-time computation involves division. Any division can be approximated to varying degrees by different combinations of multiplication and bit shift. For example, to divide an <code>int16_t</code> by <code>7</code> using an <code>int32_t</code>:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb35-1" title="1"><span class="dt">int16_t</span> divide_by_seven(<span class="dt">int16_t</span> n) {</a>
<a class="sourceLine" id="cb35-2" title="2">    <span class="cf">return</span> (n * <span class="dv">37449</span>) &gt;&gt; <span class="dv">18</span>;</a>
<a class="sourceLine" id="cb35-3" title="3">}</a></code></pre></div>
<p>Unfortunately, the coefficient is costly to calculate and the operation requires additional width. If the divisor and headroom is known at compile-time, the calculation can potentially outperform a division operation.</p>
<h3><a id="advanced_topics-user_defined_literals"></a>User-defined Literals</h3>
<p>It is possible to improve on <code>std::integral_constant</code> in various ways. Consider:</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb36-1" title="1"><span class="kw">template</span>&lt;</a>
<a class="sourceLine" id="cb36-2" title="2">    <span class="kw">class</span> Integral,</a>
<a class="sourceLine" id="cb36-3" title="3">    Integral Value,</a>
<a class="sourceLine" id="cb36-4" title="4">    <span class="dt">int</span> Digits = calculate_digits(Value),</a>
<a class="sourceLine" id="cb36-5" title="5">    <span class="dt">int</span> Zeros = calculate_zeros(Value)&gt;</a>
<a class="sourceLine" id="cb36-6" title="6"><span class="kw">class</span> const_integer {};</a></code></pre></div>
<p>This type resembles <code>integral_constant</code> with two additional non-type parameters:</p>
<ul>
<li>Digits - the numbers of digits required to store <code>Value</code>;</li>
<li>Zeros - the number of trailing binary <code>0</code>s between the least significant binary <code>1</code> and the radix position.</li>
</ul>
<p>For example:</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb37-1" title="1"><span class="kw">auto</span> m = const_integer&lt;<span class="dt">int</span>, <span class="dv">10</span>&gt;{};  <span class="co">// Value = 0b1010, Digits = 4, Zeros = 1</span></a>
<a class="sourceLine" id="cb37-2" title="2"><span class="kw">auto</span> n = const_integer&lt;<span class="dt">int</span>, <span class="dv">96</span>&gt;{};  <span class="co">//xx Value = 0b1100000, Digits = 7, Zeros = 5</span></a></code></pre></div>
<p>Now consider a user-defined literal which provides a shorthand for <code>const_integer</code> values:</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb38-1" title="1"><span class="kw">auto</span> m = <span class="dv">10_c</span>;  <span class="co">// const_integer&lt;int, 10&gt;{}</span></a>
<a class="sourceLine" id="cb38-2" title="2"><span class="kw">auto</span> n = <span class="dv">96_c</span>;  <span class="co">// const_integer&lt;int, 96&gt;{}</span></a></code></pre></div>
<p>Finally, combine these user-defined literals with class template deduction. The <code>Digits</code> and <code>Zeros</code> parameters of <code>const_integer</code> can be matched with the template parameters of composite types:</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb39-1" title="1"><span class="kw">auto</span> e = elastic_integer(<span class="dv">10_c</span>);  <span class="co">// elastic_integer&lt;4, int&gt;{10}</span></a>
<a class="sourceLine" id="cb39-2" title="2"><span class="kw">auto</span> f = scaled_integer(<span class="dv">96_c</span>); <span class="co">// scaled_integer&lt;int, power&lt;5&gt;&gt;{96}</span></a></code></pre></div>
<p>The result is easy to read formulation of tailored composite types. Unfortunately, class template deduction does not extend to aliases. Because of this, it is not yet possible to write definitions such as:</p>
<div class="sourceCode" id="cb40"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb40-1" title="1"><span class="kw">auto</span> kibi = elastic_scaled_integer(<span class="dv">1024_c</span>);  <span class="co">// stores value 1024 using 2 bits</span></a>
<a class="sourceLine" id="cb40-2" title="2"><span class="kw">auto</span> half = kibi / <span class="dv">2048_c</span>;  <span class="co">// stores value 0.5 using 3 bits</span></a></code></pre></div>
<h2><a id="acknowledgements"></a>Acknowledgements</h2>
<p>Thanks to Lawrence Crowl and Jens Maurer for valuable feedback on early drafts. Special thanks to Michael Wong and Davis Herring for extensive and invaluable support and input on this topic.</p>
</body>
</html>
