Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / doc / html / boost_multiprecision / intro.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
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&#160;1.&#160;Boost.Multiprecision">
8 <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Multiprecision">
9 <link rel="prev" href="../index.html" title="Chapter&#160;1.&#160;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 Numbers">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 built-in types.
34       The big number types in Multiprecision can be used with a wide selection of
35       basic mathematical operations, elementary transcendental functions as well
36       as the functions in Boost.Math. The Multiprecision types can also interoperate
37       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&#160;1.1.&#160;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&#160;1.2.&#160;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&#160;1.3.&#160;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 &#169; 2002-2019 John Maddock
776       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>