<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Introduction</title>
-<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<link rel="stylesheet" href="../multiprecision.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Chapter 1. Boost.Multiprecision">
<link rel="up" href="../index.html" title="Chapter 1. Boost.Multiprecision">
The big number types in Multiprecision can be used with a wide selection of
basic mathematical operations, elementary transcendental functions as well
as the functions in Boost.Math. The Multiprecision types can also interoperate
- with the built-in types in C++ using clearly defined conversion rules. This
+ with any <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
+ (built-in) type</a> in C++ using clearly defined conversion rules. This
allows Boost.Multiprecision to be used for all kinds of mathematical calculations
involving integer, rational and floating-point types requiring extended range
and precision.
</p>
<p>
Multiprecision consists of a generic interface to the mathematics of large
- numbers as well as a selection of big number back ends, with support for integer,
+ numbers as well as a selection of big number back-ends, with support for integer,
rational, floating-point, and complex types. Boost.Multiprecision provides
- a selection of back ends provided off-the-rack in including interfaces to GMP,
+ a selection of back-ends provided off-the-rack in including interfaces to GMP,
MPFR, MPIR, MPC, TomMath as well as its own collection of Boost-licensed, header-only
- back ends for integers, rationals and floats. In addition, user-defined back
- ends can be created and used with the interface of Multiprecision, provided
- the class implementation adheres to the necessary <a class="link" href="ref/backendconc.html" title="Backend Requirements">concepts</a>.
+ back-ends for integers, rationals and floats. In addition, user-defined back-ends
+ can be created and used with the interface of Multiprecision, provided the
+ class implementation adheres to the necessary <a class="link" href="ref/backendconc.html" title="Backend Requirements">concepts</a>.
</p>
<p>
Depending upon the number type, precision may be arbitrarily large (limited
- only by available memory), fixed at compile time (for example 50 or 100 decimal
+ only by available memory), fixed at compile time (for example, 50 or 100 decimal
digits), or a variable controlled at run-time by member functions. The types
- are expression-template-enabled for better performance than naive user-defined
+ are <a href="https://en.wikipedia.org/wiki/Expression_templates" target="_top">expression
+ templates</a> - enabled for better performance than naive user-defined
types.
</p>
<p>
back-ends rely on 3rd party libraries, but a header-only Boost license version
is always available (if somewhat slower).
</p>
+<h6>
+<a name="boost_multiprecision.intro.h0"></a>
+ <span class="phrase"><a name="boost_multiprecision.intro.getting_started"></a></span><a class="link" href="intro.html#boost_multiprecision.intro.getting_started">Getting
+ started with Boost.Multiprecision</a>
+ </h6>
+<p>
+ Should you just wish to 'cut to the chase' just to get bigger integers and/or
+ bigger and more precise reals as simply and portably as possible, close to
+ 'drop-in' replacements for the <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
+ (built-in) type</a> analogs, then use a fully Boost-licensed number type,
+ and skip to one of more of :
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
+<li class="listitem">
+ <a class="link" href="tut/ints/cpp_int.html" title="cpp_int">cpp_int</a> for
+ multiprecision integers,
+ </li>
+<li class="listitem">
+ <a class="link" href="tut/rational/cpp_rational.html" title="cpp_rational">cpp_rational</a>
+ for rational types,
+ </li>
+<li class="listitem">
+ <a class="link" href="tut/floats/cpp_bin_float.html" title="cpp_bin_float">cpp_bin_float</a>
+ and <a class="link" href="tut/floats/cpp_dec_float.html" title="cpp_dec_float">cpp_dec_float</a>
+ for multiprecision floating-point types,
+ </li>
+<li class="listitem">
+ <a class="link" href="tut/complex/cpp_complex.html" title="cpp_complex">cpp_complex</a>
+ for complex types.
+ </li>
+</ul></div>
<p>
- Should you just wish to cut to the chase and use a fully Boost-licensed number
- type, then skip to <a class="link" href="tut/ints/cpp_int.html" title="cpp_int">cpp_int</a>
- for multiprecision integers, <a class="link" href="tut/rational/cpp_rational.html" title="cpp_rational">cpp_rational</a>
- for rational types, <a class="link" href="tut/floats/cpp_dec_float.html" title="cpp_dec_float">cpp_dec_float</a>
- for multiprecision floating-point types and <a class="link" href="tut/complex/cpp_complex.html" title="cpp_complex">cpp_complex</a>
- for complex types.
+ 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>
+ 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>.
</p>
<p>
- The library is often used via one of the predefined typedefs: for example if
- you wanted an <a href="http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic" target="_top">arbitrary
+ For example, if you want a signed, 128-bit fixed size integer:
+ </p>
+<pre class="programlisting"><span class="preprocessor">#include</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="identifier">cpp_int</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// Integer types.</span>
+
+<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>
+</pre>
+<p>
+ Alternatively, and more adventurously, if you wanted an <a href="http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic" target="_top">arbitrary
precision</a> integer type using <a href="http://gmplib.org" target="_top">GMP</a>
as the underlying implementation then you could use:
</p>
<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>
</pre>
<p>
- Alternatively, you can compose your own multiprecision type, by combining
+ Or for a simple, portable 128-bit floating-point close to a drop-in for a
+ <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental (built-in)
+ type</a> like <code class="computeroutput"><span class="keyword">double</span></code>, usually
+ 64-bit
+ </p>
+<pre class="programlisting"><span class="preprocessor">#include</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="identifier">cpp_bin_float</span><span class="special">.</span><span class="identifier">hpp</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="identifier">cpp_bin_float_quad</span> <span class="identifier">my_quad_real</span><span class="special">;</span>
+</pre>
+<p>
+ Alternatively, you can compose your own 'custom' multiprecision type, by combining
<code class="computeroutput"><span class="identifier">number</span></code> with one of the predefined
back-end types. For example, suppose you wanted a 300 decimal digit floating-point
type based on the <a href="http://www.mpfr.org" target="_top">MPFR</a> library. In
- this case, there's no predefined typedef with that level of precision, so instead
- we compose our own:
+ this case, there's no predefined <code class="computeroutput"><span class="keyword">typedef</span></code>
+ with that level of precision, so instead we compose our own:
</p>
-<pre class="programlisting"><span class="preprocessor">#include</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="identifier">mpfr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// Defines the Backend type that wraps MPFR</span>
+<pre class="programlisting"><span class="preprocessor">#include</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="identifier">mpfr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// Defines the Backend type that wraps MPFR.</span>
<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>
<span class="keyword">typedef</span> <span class="identifier">mp</span><span class="special">::</span><span class="identifier">number</span><span class="special"><</span><span class="identifier">mp</span><span class="special">::</span><span class="identifier">mpfr_float_backend</span><span class="special"><</span><span class="number">300</span><span class="special">></span> <span class="special">></span> <span class="identifier">my_float</span><span class="special">;</span>
-<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>
+<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>
</pre>
<p>
We can repeat the above example, but with the expression templates disabled
(for faster compile times, but slower runtimes) by passing a second template
argument to <code class="computeroutput"><span class="identifier">number</span></code>:
</p>
-<pre class="programlisting"><span class="preprocessor">#include</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="identifier">mpfr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// Defines the Backend type that wraps MPFR</span>
+<pre class="programlisting"><span class="preprocessor">#include</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="identifier">mpfr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// Defines the Backend type that wraps MPFR.</span>
<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>
<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>
</pre>
<h5>
-<a name="boost_multiprecision.intro.h0"></a>
+<a name="boost_multiprecision.intro.h1"></a>
<span class="phrase"><a name="boost_multiprecision.intro.move_semantics"></a></span><a class="link" href="intro.html#boost_multiprecision.intro.move_semantics">Move
Semantics</a>
</h5>
library containers.
</p>
<h5>
-<a name="boost_multiprecision.intro.h1"></a>
+<a name="boost_multiprecision.intro.h2"></a>
<span class="phrase"><a name="boost_multiprecision.intro.expression_templates"></a></span><a class="link" href="intro.html#boost_multiprecision.intro.expression_templates">Expression
Templates</a>
</h5>
<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"><</span><span class="identifier">Backend</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">number</span><span class="special"><</span><span class="identifier">Backend</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
</pre>
<p>
- Where the "unmentionable" return type is an implementation detail
- that, rather than containing the result of the multiplication, contains instructions
- on how to compute the result. In effect it's just a pair of references to the
- arguments of the function, plus some compile-time information that stores what
- the operation is.
+ Where the '<span class="emphasis"><em>unmentionable</em></span>' return type is an implementation
+ detail that, rather than containing the result of the multiplication, contains
+ instructions on how to compute the result. In effect it's just a pair of references
+ to the arguments of the function, plus some compile-time information that stores
+ what the operation is.
</p>
<p>
The great advantage of this method is the <span class="emphasis"><em>elimination of temporaries</em></span>:
- 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
+ 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
the result, and at least another one to return it. It's true that sometimes
this overhead can be reduced by using move-semantics, but it can't be eliminated
completely. For example, lets suppose we're evaluating a polynomial via Horner's
will outlive that of <code class="computeroutput"><span class="identifier">my_expression</span></code>.
</p>
<p>
- In fact it is particularly easy to create dangling references by mixing expression
- templates with the auto keyword, for example:
+ In fact, it is particularly easy to create dangling references by mixing
+ expression templates with the <code class="computeroutput"><span class="keyword">auto</span></code>
+ keyword, for example:
</p>
<p>
<code class="computeroutput"><span class="keyword">auto</span> <span class="identifier">val</span>
<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>
</p>
<p>
- In this situation the integer literal is stored directly in the expression
- template - so its use is OK here - but the cpp_dec_float_50 temporary is
- stored by reference and then destructed when the statement completes leaving
- a dangling reference.
+ In this situation, the integer literal is stored directly in the expression
+ template - so its use is OK here - but the <code class="computeroutput"><span class="identifier">cpp_dec_float_50</span></code>
+ temporary is stored by reference and then destructed when the statement completes,
+ leaving a dangling reference.
</p>
<p>
<span class="bold"><strong><span class="emphasis"><em>If in doubt, do not ever mix expression templates
- with the auto keyword.</em></span></strong></span>
+ with the <code class="computeroutput"><span class="keyword">auto</span></code> keyword.</em></span></strong></span>
</p>
</td></tr>
</table></div>
<p>
And finally... the performance improvements from an expression template library
like this are often not as dramatic as the reduction in number of temporaries
- would suggest. For example if we compare this library with <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
+ would suggest. For example, if we compare this library with <a href="http://math.berkeley.edu/~wilken/code/gmpfrxx/" target="_top">mpfr_class</a>
and <a href="http://www.holoborodko.com/pavel/mpfr/" target="_top">mpreal</a>, with
all three using the underlying <a href="http://www.mpfr.org" target="_top">MPFR</a>
library at 50 decimal digits precision then we see the following typical results
<div id="ftn.boost_multiprecision.intro.f0" class="footnote"><p><a href="#boost_multiprecision.intro.f0" class="para"><sup class="para">[1] </sup></a>
The actual number generated will depend on the compiler, how well it optimizes
the code, and whether it supports rvalue references. The number of 11 temporaries
- was generated with Visual C++ 10
+ was generated with Visual C++ 2010.
</p></div>
</div>
</div>