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