intro.html 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  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. <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>
  122. </pre>
  123. <p>
  124. Alternatively, and more adventurously, if you wanted an <a href="http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic" target="_top">arbitrary
  125. precision</a> integer type using <a href="http://gmplib.org" target="_top">GMP</a>
  126. as the underlying implementation then you could use:
  127. </p>
  128. <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>
  129. <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>
  130. </pre>
  131. <p>
  132. Or for a simple, portable 128-bit floating-point close to a drop-in for a
  133. <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental (built-in)
  134. type</a> like <code class="computeroutput"><span class="keyword">double</span></code>, usually
  135. 64-bit
  136. </p>
  137. <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>
  138. <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>
  139. </pre>
  140. <p>
  141. Alternatively, you can compose your own 'custom' multiprecision type, by combining
  142. <code class="computeroutput"><span class="identifier">number</span></code> with one of the predefined
  143. back-end types. For example, suppose you wanted a 300 decimal digit floating-point
  144. type based on the <a href="http://www.mpfr.org" target="_top">MPFR</a> library. In
  145. this case, there's no predefined <code class="computeroutput"><span class="keyword">typedef</span></code>
  146. with that level of precision, so instead we compose our own:
  147. </p>
  148. <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>
  149. <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>
  150. <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>
  151. <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>
  152. </pre>
  153. <p>
  154. We can repeat the above example, but with the expression templates disabled
  155. (for faster compile times, but slower runtimes) by passing a second template
  156. argument to <code class="computeroutput"><span class="identifier">number</span></code>:
  157. </p>
  158. <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>
  159. <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>
  160. <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>
  161. <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>
  162. </pre>
  163. <p>
  164. We can also mix arithmetic operations between different types, provided there
  165. is an unambiguous implicit conversion from one type to the other:
  166. </p>
  167. <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>
  168. <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>
  169. <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>
  170. <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>
  171. <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>
  172. </pre>
  173. <p>
  174. Conversions are also allowed:
  175. </p>
  176. <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>
  177. <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>
  178. </pre>
  179. <p>
  180. However conversions that are inherently lossy are either declared explicit
  181. or else forbidden altogether:
  182. </p>
  183. <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>
  184. <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>
  185. </pre>
  186. <p>
  187. Mixed arithmetic will fail if the conversion is either ambiguous or explicit:
  188. </p>
  189. <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>
  190. <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>
  191. <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>
  192. <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>
  193. </pre>
  194. <h5>
  195. <a name="boost_multiprecision.intro.h1"></a>
  196. <span class="phrase"><a name="boost_multiprecision.intro.move_semantics"></a></span><a class="link" href="intro.html#boost_multiprecision.intro.move_semantics">Move
  197. Semantics</a>
  198. </h5>
  199. <p>
  200. On compilers that support rvalue-references, class <code class="computeroutput"><span class="identifier">number</span></code>
  201. is move-enabled if the underlying backend is.
  202. </p>
  203. <p>
  204. In addition the non-expression template operator overloads (see below) are
  205. move aware and have overloads that look something like:
  206. </p>
  207. <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>
  208. <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>
  209. <span class="special">{</span>
  210. <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>
  211. <span class="special">}</span>
  212. </pre>
  213. <p>
  214. These operator overloads ensure that many expressions can be evaluated without
  215. actually generating any temporaries. However, there are still many simple expressions
  216. such as
  217. </p>
  218. <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>
  219. </pre>
  220. <p>
  221. which don't noticeably benefit from move support. Therefore, optimal performance
  222. comes from having both move-support, and expression templates enabled.
  223. </p>
  224. <p>
  225. Note that while "moved-from" objects are left in a sane state, they
  226. have an unspecified value, and the only permitted operations on them are destruction
  227. or the assignment of a new value. Any other operation should be considered
  228. a programming error and all of our backends will trigger an assertion if any
  229. other operation is attempted. This behavior allows for optimal performance
  230. on move-construction (i.e. no allocation required, we just take ownership of
  231. the existing object's internal state), while maintaining usability in the standard
  232. library containers.
  233. </p>
  234. <h5>
  235. <a name="boost_multiprecision.intro.h2"></a>
  236. <span class="phrase"><a name="boost_multiprecision.intro.expression_templates"></a></span><a class="link" href="intro.html#boost_multiprecision.intro.expression_templates">Expression
  237. Templates</a>
  238. </h5>
  239. <p>
  240. Class <code class="computeroutput"><span class="identifier">number</span></code> is expression-template-enabled:
  241. that means that rather than having a multiplication operator that looks like
  242. this:
  243. </p>
  244. <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>
  245. <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>
  246. <span class="special">{</span>
  247. <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>
  248. <span class="identifier">result</span> <span class="special">*=</span> <span class="identifier">b</span><span class="special">;</span>
  249. <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
  250. <span class="special">}</span>
  251. </pre>
  252. <p>
  253. Instead the operator looks more like this:
  254. </p>
  255. <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>
  256. <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>
  257. </pre>
  258. <p>
  259. Where the '<span class="emphasis"><em>unmentionable</em></span>' return type is an implementation
  260. detail that, rather than containing the result of the multiplication, contains
  261. instructions on how to compute the result. In effect it's just a pair of references
  262. to the arguments of the function, plus some compile-time information that stores
  263. what the operation is.
  264. </p>
  265. <p>
  266. The great advantage of this method is the <span class="emphasis"><em>elimination of temporaries</em></span>:
  267. 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
  268. the result, and at least another one to return it. It's true that sometimes
  269. this overhead can be reduced by using move-semantics, but it can't be eliminated
  270. completely. For example, lets suppose we're evaluating a polynomial via Horner's
  271. method, something like this:
  272. </p>
  273. <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>
  274. <span class="comment">//....</span>
  275. <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>
  276. </pre>
  277. <p>
  278. 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
  279. <span class="emphasis"><em>without creating a single temporary value</em></span>. In contrast,
  280. if we were using the <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
  281. C++ wrapper for <a href="http://www.mpfr.org" target="_top">MPFR</a> - then this expression
  282. 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
  283. use expression templates to reduce the number of temporaries somewhat). Had
  284. we used an even simpler wrapper around <a href="http://www.mpfr.org" target="_top">MPFR</a>
  285. like <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a> things
  286. would have been even worse and no less that 24 temporaries are created for
  287. this simple expression (note - we actually measure the number of memory allocations
  288. performed rather than the number of temporaries directly, note also that the
  289. <a href="http://gmplib.org/manual/C_002b_002b-Interface-Floats.html#C_002b_002b-Interface-Floats" target="_top">mpf_class</a>
  290. wrapper that will be supplied with GMP-5.1 reduces the number of temporaries
  291. to pretty much zero). Note that if we compile with expression templates disabled
  292. and rvalue-reference support on, then actually still have no wasted memory
  293. allocations as even though temporaries are created, their contents are moved
  294. rather than copied. <a href="#ftn.boost_multiprecision.intro.f0" class="footnote" name="boost_multiprecision.intro.f0"><sup class="footnote">[1]</sup></a>
  295. </p>
  296. <div class="important"><table border="0" summary="Important">
  297. <tr>
  298. <td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
  299. <th align="left">Important</th>
  300. </tr>
  301. <tr><td align="left" valign="top">
  302. <p>
  303. Expression templates can radically reorder the operations in an expression,
  304. for example:
  305. </p>
  306. <p>
  307. a = (b * c) * a;
  308. </p>
  309. <p>
  310. Will get transformed into:
  311. </p>
  312. <p>
  313. a *= c; a *= b;
  314. </p>
  315. <p>
  316. If this is likely to be an issue for a particular application, then they
  317. should be disabled.
  318. </p>
  319. </td></tr>
  320. </table></div>
  321. <p>
  322. This library also extends expression template support to standard library functions
  323. like <code class="computeroutput"><span class="identifier">abs</span></code> or <code class="computeroutput"><span class="identifier">sin</span></code>
  324. with <code class="computeroutput"><span class="identifier">number</span></code> arguments. This
  325. means that an expression such as:
  326. </p>
  327. <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>
  328. </pre>
  329. <p>
  330. can be evaluated without a single temporary being calculated. Even expressions
  331. like:
  332. </p>
  333. <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>
  334. </pre>
  335. <p>
  336. get this treatment, so that variable 'y' is used as "working storage"
  337. within the implementation of <code class="computeroutput"><span class="identifier">sin</span></code>,
  338. thus reducing the number of temporaries used by one. Of course, should you
  339. write:
  340. </p>
  341. <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>
  342. </pre>
  343. <p>
  344. Then we clearly can't use <code class="computeroutput"><span class="identifier">x</span></code>
  345. as working storage during the calculation, so then a temporary variable is
  346. created in this case.
  347. </p>
  348. <p>
  349. Given the comments above, you might be forgiven for thinking that expression-templates
  350. are some kind of universal-panacea: sadly though, all tricks like this have
  351. their downsides. For one thing, expression template libraries like this one,
  352. tend to be slower to compile than their simpler cousins, they're also harder
  353. to debug (should you actually want to step through our code!), and rely on
  354. compiler optimizations being turned on to give really good performance. Also,
  355. since the return type from expressions involving <code class="computeroutput"><span class="identifier">number</span></code>s
  356. is an "unmentionable implementation detail", you have to be careful
  357. to cast the result of an expression to the actual number type when passing
  358. an expression to a template function. For example, given:
  359. </p>
  360. <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>
  361. <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>
  362. </pre>
  363. <p>
  364. Then calling:
  365. </p>
  366. <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>
  367. </pre>
  368. <p>
  369. 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
  370. template type, and not a number type. Instead we probably need:
  371. </p>
  372. <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>
  373. </pre>
  374. <p>
  375. Having said that, these situations don't occur that often - or indeed not at
  376. all for non-template functions. In addition, all the functions in the Boost.Math
  377. library will automatically convert expression-template arguments to the underlying
  378. number type without you having to do anything, so:
  379. </p>
  380. <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>
  381. <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>
  382. </pre>
  383. <p>
  384. 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
  385. template argument getting converted to an <code class="computeroutput"><span class="identifier">mpfr_float_100</span></code>
  386. internally by the Boost.Math library.
  387. </p>
  388. <div class="caution"><table border="0" summary="Caution">
  389. <tr>
  390. <td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../../../doc/src/images/caution.png"></td>
  391. <th align="left">Caution</th>
  392. </tr>
  393. <tr><td align="left" valign="top">
  394. <p>
  395. In C++11 you should never store an expression template using:
  396. </p>
  397. <p>
  398. <code class="computeroutput"><span class="keyword">auto</span> <span class="identifier">my_expression</span>
  399. <span class="special">=</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span> <span class="special">-</span>
  400. <span class="identifier">c</span><span class="special">;</span></code>
  401. </p>
  402. <p>
  403. unless you're absolutely sure that the lifetimes of <code class="computeroutput"><span class="identifier">a</span></code>,
  404. <code class="computeroutput"><span class="identifier">b</span></code> and <code class="computeroutput"><span class="identifier">c</span></code>
  405. will outlive that of <code class="computeroutput"><span class="identifier">my_expression</span></code>.
  406. </p>
  407. <p>
  408. In fact, it is particularly easy to create dangling references by mixing
  409. expression templates with the <code class="computeroutput"><span class="keyword">auto</span></code>
  410. keyword, for example:
  411. </p>
  412. <p>
  413. <code class="computeroutput"><span class="keyword">auto</span> <span class="identifier">val</span>
  414. <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>
  415. </p>
  416. <p>
  417. In this situation, the integer literal is stored directly in the expression
  418. template - so its use is OK here - but the <code class="computeroutput"><span class="identifier">cpp_dec_float_50</span></code>
  419. temporary is stored by reference and then destructed when the statement completes,
  420. leaving a dangling reference.
  421. </p>
  422. <p>
  423. <span class="bold"><strong><span class="emphasis"><em>If in doubt, do not ever mix expression templates
  424. with the <code class="computeroutput"><span class="keyword">auto</span></code> keyword.</em></span></strong></span>
  425. </p>
  426. </td></tr>
  427. </table></div>
  428. <p>
  429. And finally... the performance improvements from an expression template library
  430. like this are often not as dramatic as the reduction in number of temporaries
  431. would suggest. For example, if we compare this library with <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
  432. and <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a>, with
  433. all three using the underlying <a href="http://www.mpfr.org" target="_top">MPFR</a>
  434. library at 50 decimal digits precision then we see the following typical results
  435. for polynomial execution:
  436. </p>
  437. <div class="table">
  438. <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>
  439. <div class="table-contents"><table class="table" summary="Evaluation of Order 6 Polynomial.">
  440. <colgroup>
  441. <col>
  442. <col>
  443. <col>
  444. </colgroup>
  445. <thead><tr>
  446. <th>
  447. <p>
  448. Library
  449. </p>
  450. </th>
  451. <th>
  452. <p>
  453. Relative Time
  454. </p>
  455. </th>
  456. <th>
  457. <p>
  458. Relative number of memory allocations
  459. </p>
  460. </th>
  461. </tr></thead>
  462. <tbody>
  463. <tr>
  464. <td>
  465. <p>
  466. number
  467. </p>
  468. </td>
  469. <td>
  470. <p>
  471. 1.0 (0.00957s)
  472. </p>
  473. </td>
  474. <td>
  475. <p>
  476. 1.0 (2996 total)
  477. </p>
  478. </td>
  479. </tr>
  480. <tr>
  481. <td>
  482. <p>
  483. <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
  484. </p>
  485. </td>
  486. <td>
  487. <p>
  488. 1.1 (0.0102s)
  489. </p>
  490. </td>
  491. <td>
  492. <p>
  493. 4.3 (12976 total)
  494. </p>
  495. </td>
  496. </tr>
  497. <tr>
  498. <td>
  499. <p>
  500. <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a>
  501. </p>
  502. </td>
  503. <td>
  504. <p>
  505. 1.6 (0.0151s)
  506. </p>
  507. </td>
  508. <td>
  509. <p>
  510. 9.3 (27947 total)
  511. </p>
  512. </td>
  513. </tr>
  514. </tbody>
  515. </table></div>
  516. </div>
  517. <br class="table-break"><p>
  518. As you can see, the execution time increases a lot more slowly than the number
  519. of memory allocations. There are a number of reasons for this:
  520. </p>
  521. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  522. <li class="listitem">
  523. The cost of extended-precision multiplication and division is so great,
  524. that the times taken for these tend to swamp everything else.
  525. </li>
  526. <li class="listitem">
  527. 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
  528. <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>
  529. (typically <code class="computeroutput"><span class="keyword">operator</span> <span class="special">*=</span></code>
  530. has to create a temporary workspace to carry out the multiplication, where
  531. as <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>
  532. can use the target variable as workspace). Since the expression templates
  533. carry out their magic by converting out-of-place operators to in-place
  534. ones, we necessarily take this hit. Even so the transformation is more
  535. efficient than creating the extra temporary variable, just not by as much
  536. as one would hope.
  537. </li>
  538. </ul></div>
  539. <p>
  540. Finally, note that <code class="computeroutput"><span class="identifier">number</span></code> takes
  541. a second template argument, which, when set to <code class="computeroutput"><span class="identifier">et_off</span></code>
  542. disables all the expression template machinery. The result is much faster to
  543. compile, but slower at runtime.
  544. </p>
  545. <p>
  546. We'll conclude this section by providing some more performance comparisons
  547. between these three libraries, again, all are using <a href="http://www.mpfr.org" target="_top">MPFR</a>
  548. to carry out the underlying arithmetic, and all are operating at the same precision
  549. (50 decimal digits):
  550. </p>
  551. <div class="table">
  552. <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>
  553. <div class="table-contents"><table class="table" summary="Evaluation of Boost.Math's Bessel function test data">
  554. <colgroup>
  555. <col>
  556. <col>
  557. <col>
  558. </colgroup>
  559. <thead><tr>
  560. <th>
  561. <p>
  562. Library
  563. </p>
  564. </th>
  565. <th>
  566. <p>
  567. Relative Time
  568. </p>
  569. </th>
  570. <th>
  571. <p>
  572. Relative Number of Memory Allocations
  573. </p>
  574. </th>
  575. </tr></thead>
  576. <tbody>
  577. <tr>
  578. <td>
  579. <p>
  580. mpfr_float_50
  581. </p>
  582. </td>
  583. <td>
  584. <p>
  585. 1.0 (5.78s)
  586. </p>
  587. </td>
  588. <td>
  589. <p>
  590. 1.0 (1611963)
  591. </p>
  592. </td>
  593. </tr>
  594. <tr>
  595. <td>
  596. <p>
  597. number&lt;mpfr_float_backend&lt;50&gt;, et_off&gt;<br> (but with
  598. rvalue reference support)
  599. </p>
  600. </td>
  601. <td>
  602. <p>
  603. 1.1 (6.29s)
  604. </p>
  605. </td>
  606. <td>
  607. <p>
  608. 2.64 (4260868)
  609. </p>
  610. </td>
  611. </tr>
  612. <tr>
  613. <td>
  614. <p>
  615. <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
  616. </p>
  617. </td>
  618. <td>
  619. <p>
  620. 1.1 (6.28s)
  621. </p>
  622. </td>
  623. <td>
  624. <p>
  625. 2.45 (3948316)
  626. </p>
  627. </td>
  628. </tr>
  629. <tr>
  630. <td>
  631. <p>
  632. <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a>
  633. </p>
  634. </td>
  635. <td>
  636. <p>
  637. 1.65 (9.54s)
  638. </p>
  639. </td>
  640. <td>
  641. <p>
  642. 8.21 (13226029)
  643. </p>
  644. </td>
  645. </tr>
  646. </tbody>
  647. </table></div>
  648. </div>
  649. <br class="table-break"><div class="table">
  650. <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>
  651. <div class="table-contents"><table class="table" summary="Evaluation of Boost.Math's Non-Central T distribution test data">
  652. <colgroup>
  653. <col>
  654. <col>
  655. <col>
  656. </colgroup>
  657. <thead><tr>
  658. <th>
  659. <p>
  660. Library
  661. </p>
  662. </th>
  663. <th>
  664. <p>
  665. Relative Time
  666. </p>
  667. </th>
  668. <th>
  669. <p>
  670. Relative Number of Memory Allocations
  671. </p>
  672. </th>
  673. </tr></thead>
  674. <tbody>
  675. <tr>
  676. <td>
  677. <p>
  678. number
  679. </p>
  680. </td>
  681. <td>
  682. <p>
  683. 1.0 (263s)
  684. </p>
  685. </td>
  686. <td>
  687. <p>
  688. 1.0 (127710873)
  689. </p>
  690. </td>
  691. </tr>
  692. <tr>
  693. <td>
  694. <p>
  695. number&lt;mpfr_float_backend&lt;50&gt;, et_off&gt;<br> (but with
  696. rvalue reference support)
  697. </p>
  698. </td>
  699. <td>
  700. <p>
  701. 1.0 (260s)
  702. </p>
  703. </td>
  704. <td>
  705. <p>
  706. 1.2 (156797871)
  707. </p>
  708. </td>
  709. </tr>
  710. <tr>
  711. <td>
  712. <p>
  713. <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
  714. </p>
  715. </td>
  716. <td>
  717. <p>
  718. 1.1 (287s)
  719. </p>
  720. </td>
  721. <td>
  722. <p>
  723. 2.1 (268336640)
  724. </p>
  725. </td>
  726. </tr>
  727. <tr>
  728. <td>
  729. <p>
  730. <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a>
  731. </p>
  732. </td>
  733. <td>
  734. <p>
  735. 1.5 (389s)
  736. </p>
  737. </td>
  738. <td>
  739. <p>
  740. 3.6 (466960653)
  741. </p>
  742. </td>
  743. </tr>
  744. </tbody>
  745. </table></div>
  746. </div>
  747. <br class="table-break"><p>
  748. The above results were generated on Win32 compiling with Visual C++ 2010, all
  749. optimizations on (/Ox), with MPFR 3.0 and MPIR 2.3.0.
  750. </p>
  751. <div class="footnotes">
  752. <br><hr style="width:100; text-align:left;margin-left: 0">
  753. <div id="ftn.boost_multiprecision.intro.f0" class="footnote"><p><a href="#boost_multiprecision.intro.f0" class="para"><sup class="para">[1] </sup></a>
  754. The actual number generated will depend on the compiler, how well it optimizes
  755. the code, and whether it supports rvalue references. The number of 11 temporaries
  756. was generated with Visual C++ 2010.
  757. </p></div>
  758. </div>
  759. </div>
  760. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  761. <td align="left"></td>
  762. <td align="right"><div class="copyright-footer">Copyright &#169; 2002-2019 John Maddock
  763. and Christopher Kormanyos<p>
  764. Distributed under the Boost Software License, Version 1.0. (See accompanying
  765. 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>)
  766. </p>
  767. </div></td>
  768. </tr></table>
  769. <hr>
  770. <div class="spirit-nav">
  771. <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>
  772. </div>
  773. </body>
  774. </html>