• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Introduction</title>
5<link rel="stylesheet" href="../multiprecision.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../index.html" title="Chapter 1. Boost.Multiprecision">
8<link rel="up" href="../index.html" title="Chapter 1. Boost.Multiprecision">
9<link rel="prev" href="../index.html" title="Chapter 1. Boost.Multiprecision">
10<link rel="next" href="tut.html" title="Tutorial">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tut.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h2 class="title" style="clear: both">
27<a name="boost_multiprecision.intro"></a><a class="link" href="intro.html" title="Introduction">Introduction</a>
28</h2></div></div></div>
29<p>
30      The Multiprecision Library provides <a class="link" href="tut/ints.html" title="Integer Types">integer</a>,
31      <a class="link" href="tut/rational.html" title="Rational Number Types">rational</a>, <a class="link" href="tut/floats.html" title="Floating-point Types">floating-point</a>,
32      and <a class="link" href="tut/complex.html" title="Complex Number Types">complex</a> types in
33      C++ that have more range and precision than C++'s ordinary <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
34      (built-in)</a> types. The big number types in Multiprecision can be used
35      with a wide selection of basic mathematical operations, elementary transcendental
36      functions as well as the functions in Boost.Math. The Multiprecision types
37      can also interoperate with any <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
38      (built-in) type</a> in C++ using clearly defined conversion rules. This
39      allows Boost.Multiprecision to be used for all kinds of mathematical calculations
40      involving integer, rational and floating-point types requiring extended range
41      and precision.
42    </p>
43<p>
44      Multiprecision consists of a generic interface to the mathematics of large
45      numbers as well as a selection of big number back-ends, with support for integer,
46      rational, floating-point, and complex types. Boost.Multiprecision provides
47      a selection of back-ends provided off-the-rack in including interfaces to GMP,
48      MPFR, MPIR, MPC, TomMath as well as its own collection of Boost-licensed, header-only
49      back-ends for integers, rationals and floats. In addition, user-defined back-ends
50      can be created and used with the interface of Multiprecision, provided the
51      class implementation adheres to the necessary <a class="link" href="ref/backendconc.html" title="Backend Requirements">concepts</a>.
52    </p>
53<p>
54      Depending upon the number type, precision may be arbitrarily large (limited
55      only by available memory), fixed at compile time (for example, 50 or 100 decimal
56      digits), or a variable controlled at run-time by member functions. The types
57      are <a href="https://en.wikipedia.org/wiki/Expression_templates" target="_top">expression
58      templates</a> - enabled for better performance than naive user-defined
59      types.
60    </p>
61<p>
62      The Multiprecision library comes in two distinct parts:
63    </p>
64<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
65<li class="listitem">
66          An expression-template-enabled front-end <code class="computeroutput"><span class="identifier">number</span></code>
67          that handles all the operator overloading, expression evaluation optimization,
68          and code reduction.
69        </li>
70<li class="listitem">
71          A selection of back-ends that implement the actual arithmetic operations,
72          and need conform only to the reduced interface requirements of the front-end.
73        </li>
74</ul></div>
75<p>
76      Separation of front-end and back-end allows use of highly refined, but restricted
77      license libraries where possible, but provides Boost license alternatives for
78      users who must have a portable unconstrained license. Which is to say some
79      back-ends rely on 3rd party libraries, but a header-only Boost license version
80      is always available (if somewhat slower).
81    </p>
82<h6>
83<a name="boost_multiprecision.intro.h0"></a>
84      <span class="phrase"><a name="boost_multiprecision.intro.getting_started"></a></span><a class="link" href="intro.html#boost_multiprecision.intro.getting_started">Getting
85      started with Boost.Multiprecision</a>
86    </h6>
87<p>
88      Should you just wish to 'cut to the chase' just to get bigger integers and/or
89      bigger and more precise reals as simply and portably as possible, close to
90      'drop-in' replacements for the <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
91      (built-in) type</a> analogs, then use a fully Boost-licensed number type,
92      and skip to one of more of :
93    </p>
94<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
95<li class="listitem">
96          <a class="link" href="tut/ints/cpp_int.html" title="cpp_int">cpp_int</a> for
97          multiprecision integers,
98        </li>
99<li class="listitem">
100          <a class="link" href="tut/rational/cpp_rational.html" title="cpp_rational">cpp_rational</a>
101          for rational types,
102        </li>
103<li class="listitem">
104          <a class="link" href="tut/floats/cpp_bin_float.html" title="cpp_bin_float">cpp_bin_float</a>
105          and <a class="link" href="tut/floats/cpp_dec_float.html" title="cpp_dec_float">cpp_dec_float</a>
106          for multiprecision floating-point types,
107        </li>
108<li class="listitem">
109          <a class="link" href="tut/complex/cpp_complex.html" title="cpp_complex">cpp_complex</a>
110          for complex types.
111        </li>
112</ul></div>
113<p>
114      The library is very often used via one of the predefined convenience <code class="computeroutput"><span class="keyword">typedef</span></code>s like <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">int128_t</span></code>
115      or <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_bin_float_quad</span></code>.
116    </p>
117<p>
118      For example, if you want a signed, 128-bit fixed size integer:
119    </p>
120<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">cpp_int</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>  <span class="comment">//  Integer types.</span>
121
122<span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">int128_t</span> <span class="identifier">my_128_bit_int</span><span class="special">;</span>
123</pre>
124<p>
125      Alternatively, and more adventurously, if you wanted an <a href="http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic" target="_top">arbitrary
126      precision</a> integer type using <a href="http://gmplib.org" target="_top">GMP</a>
127      as the underlying implementation then you could use:
128    </p>
129<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">gmp</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>  <span class="comment">// Defines the wrappers around the GMP library's types</span>
130
131<span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">mpz_int</span> <span class="identifier">myint</span><span class="special">;</span>    <span class="comment">// Arbitrary precision integer type.</span>
132</pre>
133<p>
134      Or for a simple, portable 128-bit floating-point close to a drop-in for a
135      <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental (built-in)
136      type</a> like <code class="computeroutput"><span class="keyword">double</span></code>, usually
137      64-bit
138    </p>
139<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">cpp_bin_float</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
140
141<span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_bin_float_quad</span> <span class="identifier">my_quad_real</span><span class="special">;</span>
142</pre>
143<p>
144      Alternatively, you can compose your own 'custom' multiprecision type, by combining
145      <code class="computeroutput"><span class="identifier">number</span></code> with one of the predefined
146      back-end types. For example, suppose you wanted a 300 decimal digit floating-point
147      type based on the <a href="http://www.mpfr.org" target="_top">MPFR</a> library. In
148      this case, there's no predefined <code class="computeroutput"><span class="keyword">typedef</span></code>
149      with that level of precision, so instead we compose our own:
150    </p>
151<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">mpfr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>  <span class="comment">// Defines the Backend type that wraps MPFR.</span>
152
153<span class="keyword">namespace</span> <span class="identifier">mp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">;</span>     <span class="comment">// Reduce the typing a bit later...</span>
154
155<span class="keyword">typedef</span> <span class="identifier">mp</span><span class="special">::</span><span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">mp</span><span class="special">::</span><span class="identifier">mpfr_float_backend</span><span class="special">&lt;</span><span class="number">300</span><span class="special">&gt;</span> <span class="special">&gt;</span>  <span class="identifier">my_float</span><span class="special">;</span>
156
157<span class="identifier">my_float</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">c</span><span class="special">;</span> <span class="comment">// These variables have 300 decimal digits precision.</span>
158</pre>
159<p>
160      We can repeat the above example, but with the expression templates disabled
161      (for faster compile times, but slower runtimes) by passing a second template
162      argument to <code class="computeroutput"><span class="identifier">number</span></code>:
163    </p>
164<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">mpfr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>  <span class="comment">// Defines the Backend type that wraps MPFR.</span>
165
166<span class="keyword">namespace</span> <span class="identifier">mp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">;</span>     <span class="comment">// Reduce the typing a bit later...</span>
167
168<span class="keyword">typedef</span> <span class="identifier">mp</span><span class="special">::</span><span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">mp</span><span class="special">::</span><span class="identifier">mpfr_float_backend</span><span class="special">&lt;</span><span class="number">300</span><span class="special">&gt;,</span> <span class="identifier">et_off</span><span class="special">&gt;</span>  <span class="identifier">my_float</span><span class="special">;</span>
169
170<span class="identifier">my_float</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">c</span><span class="special">;</span> <span class="comment">// These variables have 300 decimal digits precision</span>
171</pre>
172<p>
173      We can also mix arithmetic operations between different types, provided there
174      is an unambiguous implicit conversion from one type to the other:
175    </p>
176<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">cpp_int</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
177
178<span class="keyword">namespace</span> <span class="identifier">mp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">;</span>     <span class="comment">// Reduce the typing a bit later...</span>
179
180<span class="identifier">mp</span><span class="special">::</span><span class="identifier">int128_t</span> <span class="identifier">a</span><span class="special">(</span><span class="number">3</span><span class="special">),</span> <span class="identifier">b</span><span class="special">(</span><span class="number">4</span><span class="special">);</span>
181<span class="identifier">mp</span><span class="special">::</span><span class="identifier">int512_t</span> <span class="identifier">c</span><span class="special">(</span><span class="number">50</span><span class="special">),</span> <span class="identifier">d</span><span class="special">;</span>
182
183<span class="identifier">d</span> <span class="special">=</span> <span class="identifier">c</span> <span class="special">*</span> <span class="identifier">a</span><span class="special">;</span>   <span class="comment">// OK, result of mixed arithmetic is an int512_t</span>
184</pre>
185<p>
186      Conversions are also allowed:
187    </p>
188<pre class="programlisting"><span class="identifier">d</span> <span class="special">=</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// OK, widening conversion.</span>
189<span class="identifier">d</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">b</span><span class="special">;</span>  <span class="comment">// OK, can convert from an expression template too.</span>
190</pre>
191<p>
192      However conversions that are inherently lossy are either declared explicit
193      or else forbidden altogether:
194    </p>
195<pre class="programlisting"><span class="identifier">d</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">;</span>  <span class="comment">// Error implicit conversion from double not allowed.</span>
196<span class="identifier">d</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">mp</span><span class="special">::</span><span class="identifier">int512_t</span><span class="special">&gt;(</span><span class="number">3.14</span><span class="special">);</span>  <span class="comment">// OK explicit construction is allowed</span>
197</pre>
198<p>
199      Mixed arithmetic will fail if the conversion is either ambiguous or explicit:
200    </p>
201<pre class="programlisting"><span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">cpp_int_backend</span><span class="special">&lt;&gt;,</span> <span class="identifier">et_off</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
202<span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">cpp_int_backend</span><span class="special">&lt;&gt;,</span> <span class="identifier">et_on</span><span class="special">&gt;</span>  <span class="identifier">b</span><span class="special">(</span><span class="number">3</span><span class="special">);</span>
203
204<span class="identifier">b</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">b</span><span class="special">;</span> <span class="comment">// Error, implicit conversion could go either way.</span>
205<span class="identifier">b</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="number">3.14</span><span class="special">;</span> <span class="comment">// Error, no operator overload if the conversion would be explicit.</span>
206</pre>
207<h5>
208<a name="boost_multiprecision.intro.h1"></a>
209      <span class="phrase"><a name="boost_multiprecision.intro.move_semantics"></a></span><a class="link" href="intro.html#boost_multiprecision.intro.move_semantics">Move
210      Semantics</a>
211    </h5>
212<p>
213      On compilers that support rvalue-references, class <code class="computeroutput"><span class="identifier">number</span></code>
214      is move-enabled if the underlying backend is.
215    </p>
216<p>
217      In addition the non-expression template operator overloads (see below) are
218      move aware and have overloads that look something like:
219    </p>
220<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">B</span><span class="special">&gt;</span>
221<span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">B</span><span class="special">,</span> <span class="identifier">et_off</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">B</span><span class="special">,</span> <span class="identifier">et_off</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">B</span><span class="special">,</span> <span class="identifier">et_off</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">)</span>
222<span class="special">{</span>
223    <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">a</span> <span class="special">+=</span> <span class="identifier">b</span><span class="special">);</span>
224<span class="special">}</span>
225</pre>
226<p>
227      These operator overloads ensure that many expressions can be evaluated without
228      actually generating any temporaries. However, there are still many simple expressions
229      such as
230    </p>
231<pre class="programlisting"><span class="identifier">a</span> <span class="special">=</span> <span class="identifier">b</span> <span class="special">*</span> <span class="identifier">c</span><span class="special">;</span>
232</pre>
233<p>
234      which don't noticeably benefit from move support. Therefore, optimal performance
235      comes from having both move-support, and expression templates enabled.
236    </p>
237<p>
238      Note that while "moved-from" objects are left in a sane state, they
239      have an unspecified value, and the only permitted operations on them are destruction
240      or the assignment of a new value. Any other operation should be considered
241      a programming error and all of our backends will trigger an assertion if any
242      other operation is attempted. This behavior allows for optimal performance
243      on move-construction (i.e. no allocation required, we just take ownership of
244      the existing object's internal state), while maintaining usability in the standard
245      library containers.
246    </p>
247<h5>
248<a name="boost_multiprecision.intro.h2"></a>
249      <span class="phrase"><a name="boost_multiprecision.intro.expression_templates"></a></span><a class="link" href="intro.html#boost_multiprecision.intro.expression_templates">Expression
250      Templates</a>
251    </h5>
252<p>
253      Class <code class="computeroutput"><span class="identifier">number</span></code> is expression-template-enabled:
254      that means that rather than having a multiplication operator that looks like
255      this:
256    </p>
257<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Backend</span><span class="special">&gt;</span>
258<span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">*</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">)</span>
259<span class="special">{</span>
260   <span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span>
261   <span class="identifier">result</span> <span class="special">*=</span> <span class="identifier">b</span><span class="special">;</span>
262   <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
263<span class="special">}</span>
264</pre>
265<p>
266      Instead the operator looks more like this:
267    </p>
268<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Backend</span><span class="special">&gt;</span>
269<span class="emphasis"><em>unmentionable-type</em></span> <span class="keyword">operator</span> <span class="special">*</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>
270</pre>
271<p>
272      Where the '<span class="emphasis"><em>unmentionable</em></span>' return type is an implementation
273      detail that, rather than containing the result of the multiplication, contains
274      instructions on how to compute the result. In effect it's just a pair of references
275      to the arguments of the function, plus some compile-time information that stores
276      what the operation is.
277    </p>
278<p>
279      The great advantage of this method is the <span class="emphasis"><em>elimination of temporaries</em></span>:
280      for example, the "naive" implementation of <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code> above, requires one temporary for computing
281      the result, and at least another one to return it. It's true that sometimes
282      this overhead can be reduced by using move-semantics, but it can't be eliminated
283      completely. For example, lets suppose we're evaluating a polynomial via Horner's
284      method, something like this:
285    </p>
286<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">a</span><span class="special">[</span><span class="number">7</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span> <span class="comment">/* some values */</span> <span class="special">};</span>
287<span class="comment">//....</span>
288<span class="identifier">y</span> <span class="special">=</span> <span class="special">(((((</span><span class="identifier">a</span><span class="special">[</span><span class="number">6</span><span class="special">]</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">a</span><span class="special">[</span><span class="number">5</span><span class="special">])</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">a</span><span class="special">[</span><span class="number">4</span><span class="special">])</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">a</span><span class="special">[</span><span class="number">3</span><span class="special">])</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">a</span><span class="special">[</span><span class="number">2</span><span class="special">])</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">a</span><span class="special">[</span><span class="number">1</span><span class="special">])</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">a</span><span class="special">[</span><span class="number">0</span><span class="special">];</span>
289</pre>
290<p>
291      If type <code class="computeroutput"><span class="identifier">T</span></code> is a <code class="computeroutput"><span class="identifier">number</span></code>, then this expression is evaluated
292      <span class="emphasis"><em>without creating a single temporary value</em></span>. In contrast,
293      if we were using the <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
294      C++ wrapper for <a href="http://www.mpfr.org" target="_top">MPFR</a> - then this expression
295      would result in no less than 11 temporaries (this is true even though <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a> does
296      use expression templates to reduce the number of temporaries somewhat). Had
297      we used an even simpler wrapper around <a href="http://www.mpfr.org" target="_top">MPFR</a>
298      like <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a> things
299      would have been even worse and no less that 24 temporaries are created for
300      this simple expression (note - we actually measure the number of memory allocations
301      performed rather than the number of temporaries directly, note also that the
302      <a href="http://gmplib.org/manual/C_002b_002b-Interface-Floats.html#C_002b_002b-Interface-Floats" target="_top">mpf_class</a>
303      wrapper that will be supplied with GMP-5.1 reduces the number of temporaries
304      to pretty much zero). Note that if we compile with expression templates disabled
305      and rvalue-reference support on, then actually still have no wasted memory
306      allocations as even though temporaries are created, their contents are moved
307      rather than copied. <a href="#ftn.boost_multiprecision.intro.f0" class="footnote" name="boost_multiprecision.intro.f0"><sup class="footnote">[1]</sup></a>
308    </p>
309<div class="important"><table border="0" summary="Important">
310<tr>
311<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
312<th align="left">Important</th>
313</tr>
314<tr><td align="left" valign="top">
315<p>
316        Expression templates can radically reorder the operations in an expression,
317        for example:
318      </p>
319<p>
320        a = (b * c) * a;
321      </p>
322<p>
323        Will get transformed into:
324      </p>
325<p>
326        a *= c; a *= b;
327      </p>
328<p>
329        If this is likely to be an issue for a particular application, then they
330        should be disabled.
331      </p>
332</td></tr>
333</table></div>
334<p>
335      This library also extends expression template support to standard library functions
336      like <code class="computeroutput"><span class="identifier">abs</span></code> or <code class="computeroutput"><span class="identifier">sin</span></code>
337      with <code class="computeroutput"><span class="identifier">number</span></code> arguments. This
338      means that an expression such as:
339    </p>
340<pre class="programlisting"><span class="identifier">y</span> <span class="special">=</span> <span class="identifier">abs</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
341</pre>
342<p>
343      can be evaluated without a single temporary being calculated. Even expressions
344      like:
345    </p>
346<pre class="programlisting"><span class="identifier">y</span> <span class="special">=</span> <span class="identifier">sin</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
347</pre>
348<p>
349      get this treatment, so that variable 'y' is used as "working storage"
350      within the implementation of <code class="computeroutput"><span class="identifier">sin</span></code>,
351      thus reducing the number of temporaries used by one. Of course, should you
352      write:
353    </p>
354<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">sin</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
355</pre>
356<p>
357      Then we clearly can't use <code class="computeroutput"><span class="identifier">x</span></code>
358      as working storage during the calculation, so then a temporary variable is
359      created in this case.
360    </p>
361<p>
362      Given the comments above, you might be forgiven for thinking that expression-templates
363      are some kind of universal-panacea: sadly though, all tricks like this have
364      their downsides. For one thing, expression template libraries like this one,
365      tend to be slower to compile than their simpler cousins, they're also harder
366      to debug (should you actually want to step through our code!), and rely on
367      compiler optimizations being turned on to give really good performance. Also,
368      since the return type from expressions involving <code class="computeroutput"><span class="identifier">number</span></code>s
369      is an "unmentionable implementation detail", you have to be careful
370      to cast the result of an expression to the actual number type when passing
371      an expression to a template function. For example, given:
372    </p>
373<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
374<span class="keyword">void</span> <span class="identifier">my_proc</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;);</span>
375</pre>
376<p>
377      Then calling:
378    </p>
379<pre class="programlisting"><span class="identifier">my_proc</span><span class="special">(</span><span class="identifier">a</span><span class="special">+</span><span class="identifier">b</span><span class="special">);</span>
380</pre>
381<p>
382      Will very likely result in obscure error messages inside the body of <code class="computeroutput"><span class="identifier">my_proc</span></code> - since we've passed it an expression
383      template type, and not a number type. Instead we probably need:
384    </p>
385<pre class="programlisting"><span class="identifier">my_proc</span><span class="special">(</span><span class="identifier">my_number_type</span><span class="special">(</span><span class="identifier">a</span><span class="special">+</span><span class="identifier">b</span><span class="special">));</span>
386</pre>
387<p>
388      Having said that, these situations don't occur that often - or indeed not at
389      all for non-template functions. In addition, all the functions in the Boost.Math
390      library will automatically convert expression-template arguments to the underlying
391      number type without you having to do anything, so:
392    </p>
393<pre class="programlisting"><span class="identifier">mpfr_float_100</span> <span class="identifier">a</span><span class="special">(</span><span class="number">20</span><span class="special">),</span> <span class="identifier">delta</span><span class="special">(</span><span class="number">0.125</span><span class="special">);</span>
394<span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gamma_p</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">delta</span><span class="special">);</span>
395</pre>
396<p>
397      Will work just fine, with the <code class="computeroutput"><span class="identifier">a</span> <span class="special">+</span> <span class="identifier">delta</span></code> expression
398      template argument getting converted to an <code class="computeroutput"><span class="identifier">mpfr_float_100</span></code>
399      internally by the Boost.Math library.
400    </p>
401<div class="caution"><table border="0" summary="Caution">
402<tr>
403<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../../../doc/src/images/caution.png"></td>
404<th align="left">Caution</th>
405</tr>
406<tr><td align="left" valign="top">
407<p>
408        In C++11 you should never store an expression template using:
409      </p>
410<p>
411        <code class="computeroutput"><span class="keyword">auto</span> <span class="identifier">my_expression</span>
412        <span class="special">=</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span> <span class="special">-</span>
413        <span class="identifier">c</span><span class="special">;</span></code>
414      </p>
415<p>
416        unless you're absolutely sure that the lifetimes of <code class="computeroutput"><span class="identifier">a</span></code>,
417        <code class="computeroutput"><span class="identifier">b</span></code> and <code class="computeroutput"><span class="identifier">c</span></code>
418        will outlive that of <code class="computeroutput"><span class="identifier">my_expression</span></code>.
419      </p>
420<p>
421        In fact, it is particularly easy to create dangling references by mixing
422        expression templates with the <code class="computeroutput"><span class="keyword">auto</span></code>
423        keyword, for example:
424      </p>
425<p>
426        <code class="computeroutput"><span class="keyword">auto</span> <span class="identifier">val</span>
427        <span class="special">=</span> <span class="identifier">cpp_dec_float_50</span><span class="special">(</span><span class="string">"23.1"</span><span class="special">)</span> <span class="special">*</span> <span class="number">100</span><span class="special">;</span></code>
428      </p>
429<p>
430        In this situation, the integer literal is stored directly in the expression
431        template - so its use is OK here - but the <code class="computeroutput"><span class="identifier">cpp_dec_float_50</span></code>
432        temporary is stored by reference and then destructed when the statement completes,
433        leaving a dangling reference.
434      </p>
435<p>
436        <span class="bold"><strong><span class="emphasis"><em>If in doubt, do not ever mix expression templates
437        with the <code class="computeroutput"><span class="keyword">auto</span></code> keyword.</em></span></strong></span>
438      </p>
439</td></tr>
440</table></div>
441<p>
442      And finally... the performance improvements from an expression template library
443      like this are often not as dramatic as the reduction in number of temporaries
444      would suggest. For example, if we compare this library with <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
445      and <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a>, with
446      all three using the underlying <a href="http://www.mpfr.org" target="_top">MPFR</a>
447      library at 50 decimal digits precision then we see the following typical results
448      for polynomial execution:
449    </p>
450<div class="table">
451<a name="boost_multiprecision.intro.evaluation_of_order_6_polynomial"></a><p class="title"><b>Table 1.1. Evaluation of Order 6 Polynomial.</b></p>
452<div class="table-contents"><table class="table" summary="Evaluation of Order 6 Polynomial.">
453<colgroup>
454<col>
455<col>
456<col>
457</colgroup>
458<thead><tr>
459<th>
460              <p>
461                Library
462              </p>
463            </th>
464<th>
465              <p>
466                Relative Time
467              </p>
468            </th>
469<th>
470              <p>
471                Relative number of memory allocations
472              </p>
473            </th>
474</tr></thead>
475<tbody>
476<tr>
477<td>
478              <p>
479                number
480              </p>
481            </td>
482<td>
483              <p>
484                1.0 (0.00957s)
485              </p>
486            </td>
487<td>
488              <p>
489                1.0 (2996 total)
490              </p>
491            </td>
492</tr>
493<tr>
494<td>
495              <p>
496                <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
497              </p>
498            </td>
499<td>
500              <p>
501                1.1 (0.0102s)
502              </p>
503            </td>
504<td>
505              <p>
506                4.3 (12976 total)
507              </p>
508            </td>
509</tr>
510<tr>
511<td>
512              <p>
513                <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a>
514              </p>
515            </td>
516<td>
517              <p>
518                1.6 (0.0151s)
519              </p>
520            </td>
521<td>
522              <p>
523                9.3 (27947 total)
524              </p>
525            </td>
526</tr>
527</tbody>
528</table></div>
529</div>
530<br class="table-break"><p>
531      As you can see, the execution time increases a lot more slowly than the number
532      of memory allocations. There are a number of reasons for this:
533    </p>
534<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
535<li class="listitem">
536          The cost of extended-precision multiplication and division is so great,
537          that the times taken for these tend to swamp everything else.
538        </li>
539<li class="listitem">
540          The cost of an in-place multiplication (using <code class="computeroutput"><span class="keyword">operator</span><span class="special">*=</span></code>) tends to be more than an out-of-place
541          <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>
542          (typically <code class="computeroutput"><span class="keyword">operator</span> <span class="special">*=</span></code>
543          has to create a temporary workspace to carry out the multiplication, where
544          as <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>
545          can use the target variable as workspace). Since the expression templates
546          carry out their magic by converting out-of-place operators to in-place
547          ones, we necessarily take this hit. Even so the transformation is more
548          efficient than creating the extra temporary variable, just not by as much
549          as one would hope.
550        </li>
551</ul></div>
552<p>
553      Finally, note that <code class="computeroutput"><span class="identifier">number</span></code> takes
554      a second template argument, which, when set to <code class="computeroutput"><span class="identifier">et_off</span></code>
555      disables all the expression template machinery. The result is much faster to
556      compile, but slower at runtime.
557    </p>
558<p>
559      We'll conclude this section by providing some more performance comparisons
560      between these three libraries, again, all are using <a href="http://www.mpfr.org" target="_top">MPFR</a>
561      to carry out the underlying arithmetic, and all are operating at the same precision
562      (50 decimal digits):
563    </p>
564<div class="table">
565<a name="boost_multiprecision.intro.evaluation_of_boost_math_s_besse"></a><p class="title"><b>Table 1.2. Evaluation of Boost.Math's Bessel function test data</b></p>
566<div class="table-contents"><table class="table" summary="Evaluation of Boost.Math's Bessel function test data">
567<colgroup>
568<col>
569<col>
570<col>
571</colgroup>
572<thead><tr>
573<th>
574              <p>
575                Library
576              </p>
577            </th>
578<th>
579              <p>
580                Relative Time
581              </p>
582            </th>
583<th>
584              <p>
585                Relative Number of Memory Allocations
586              </p>
587            </th>
588</tr></thead>
589<tbody>
590<tr>
591<td>
592              <p>
593                mpfr_float_50
594              </p>
595            </td>
596<td>
597              <p>
598                1.0 (5.78s)
599              </p>
600            </td>
601<td>
602              <p>
603                1.0 (1611963)
604              </p>
605            </td>
606</tr>
607<tr>
608<td>
609              <p>
610                number&lt;mpfr_float_backend&lt;50&gt;, et_off&gt;<br> (but with
611                rvalue reference support)
612              </p>
613            </td>
614<td>
615              <p>
616                1.1 (6.29s)
617              </p>
618            </td>
619<td>
620              <p>
621                2.64 (4260868)
622              </p>
623            </td>
624</tr>
625<tr>
626<td>
627              <p>
628                <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
629              </p>
630            </td>
631<td>
632              <p>
633                1.1 (6.28s)
634              </p>
635            </td>
636<td>
637              <p>
638                2.45 (3948316)
639              </p>
640            </td>
641</tr>
642<tr>
643<td>
644              <p>
645                <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a>
646              </p>
647            </td>
648<td>
649              <p>
650                1.65 (9.54s)
651              </p>
652            </td>
653<td>
654              <p>
655                8.21 (13226029)
656              </p>
657            </td>
658</tr>
659</tbody>
660</table></div>
661</div>
662<br class="table-break"><div class="table">
663<a name="boost_multiprecision.intro.evaluation_of_boost_math_s_non_c"></a><p class="title"><b>Table 1.3. Evaluation of Boost.Math's Non-Central T distribution test data</b></p>
664<div class="table-contents"><table class="table" summary="Evaluation of Boost.Math's Non-Central T distribution test data">
665<colgroup>
666<col>
667<col>
668<col>
669</colgroup>
670<thead><tr>
671<th>
672              <p>
673                Library
674              </p>
675            </th>
676<th>
677              <p>
678                Relative Time
679              </p>
680            </th>
681<th>
682              <p>
683                Relative Number of Memory Allocations
684              </p>
685            </th>
686</tr></thead>
687<tbody>
688<tr>
689<td>
690              <p>
691                number
692              </p>
693            </td>
694<td>
695              <p>
696                1.0 (263s)
697              </p>
698            </td>
699<td>
700              <p>
701                1.0 (127710873)
702              </p>
703            </td>
704</tr>
705<tr>
706<td>
707              <p>
708                number&lt;mpfr_float_backend&lt;50&gt;, et_off&gt;<br> (but with
709                rvalue reference support)
710              </p>
711            </td>
712<td>
713              <p>
714                1.0 (260s)
715              </p>
716            </td>
717<td>
718              <p>
719                1.2 (156797871)
720              </p>
721            </td>
722</tr>
723<tr>
724<td>
725              <p>
726                <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
727              </p>
728            </td>
729<td>
730              <p>
731                1.1 (287s)
732              </p>
733            </td>
734<td>
735              <p>
736                2.1 (268336640)
737              </p>
738            </td>
739</tr>
740<tr>
741<td>
742              <p>
743                <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a>
744              </p>
745            </td>
746<td>
747              <p>
748                1.5 (389s)
749              </p>
750            </td>
751<td>
752              <p>
753                3.6 (466960653)
754              </p>
755            </td>
756</tr>
757</tbody>
758</table></div>
759</div>
760<br class="table-break"><p>
761      The above results were generated on Win32 compiling with Visual C++ 2010, all
762      optimizations on (/Ox), with MPFR 3.0 and MPIR 2.3.0.
763    </p>
764<div class="footnotes">
765<br><hr style="width:100; text-align:left;margin-left: 0">
766<div id="ftn.boost_multiprecision.intro.f0" class="footnote"><p><a href="#boost_multiprecision.intro.f0" class="para"><sup class="para">[1] </sup></a>
767        The actual number generated will depend on the compiler, how well it optimizes
768        the code, and whether it supports rvalue references. The number of 11 temporaries
769        was generated with Visual C++ 2010.
770      </p></div>
771</div>
772</div>
773<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
774<td align="left"></td>
775<td align="right"><div class="copyright-footer">Copyright © 2002-2020 John
776      Maddock and Christopher Kormanyos<p>
777        Distributed under the Boost Software License, Version 1.0. (See accompanying
778        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
779      </p>
780</div></td>
781</tr></table>
782<hr>
783<div class="spirit-nav">
784<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tut.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
785</div>
786</body>
787</html>
788