Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / doc / html / boost_multiprecision / tut / mixed.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Mixed Precision Arithmetic</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="../tut.html" title="Tutorial">
9 <link rel="prev" href="rounding.html" title="Rounding Rules for Conversions">
10 <link rel="next" href="gen_int.html" title="Generic Integer Operations">
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="rounding.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tut.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="gen_int.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
24 </div>
25 <div class="section">
26 <div class="titlepage"><div><div><h3 class="title">
27 <a name="boost_multiprecision.tut.mixed"></a><a class="link" href="mixed.html" title="Mixed Precision Arithmetic">Mixed Precision Arithmetic</a>
28 </h3></div></div></div>
29 <p>
30         Mixed precision arithmetic is fully supported by the library.
31       </p>
32 <p>
33         There are two different forms:
34       </p>
35 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
36 <li class="listitem">
37             Where the operands are of different precision.
38           </li>
39 <li class="listitem">
40             Where the operands are of the same precision, but yield a higher precision
41             result.
42           </li>
43 </ul></div>
44 <h5>
45 <a name="boost_multiprecision.tut.mixed.h0"></a>
46         <span class="phrase"><a name="boost_multiprecision.tut.mixed.mixing_operands_of_differing_pre"></a></span><a class="link" href="mixed.html#boost_multiprecision.tut.mixed.mixing_operands_of_differing_pre">Mixing
47         Operands of Differing Precision</a>
48       </h5>
49 <p>
50         If the arguments to a binary operator are of different precision, then the
51         operation is allowed as long as there is an unambiguous implicit conversion
52         from one argument type to the other. In all cases the arithmetic is performed
53         "as if" the lower precision type is promoted to the higher precision
54         type before applying the operator. However, particular backends may optimise
55         this and avoid actually creating a temporary if they are able to do so.
56       </p>
57 <p>
58         For example:
59       </p>
60 <pre class="programlisting"><span class="identifier">mpfr_float_50</span>         <span class="identifier">a</span><span class="special">(</span><span class="number">2</span><span class="special">),</span> <span class="identifier">b</span><span class="special">;</span>
61 <span class="identifier">mpfr_float_100</span>        <span class="identifier">c</span><span class="special">(</span><span class="number">3</span><span class="special">),</span> <span class="identifier">d</span><span class="special">;</span>
62 <span class="identifier">static_mpfr_float_50</span>  <span class="identifier">e</span><span class="special">(</span><span class="number">5</span><span class="special">),</span> <span class="identifier">f</span><span class="special">;</span>
63 <span class="identifier">mpz_int</span>               <span class="identifier">i</span><span class="special">(</span><span class="number">20</span><span class="special">);</span>
64
65 <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">c</span><span class="special">;</span>  <span class="comment">// OK, result of operand is an mpfr_float_100.</span>
66 <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">c</span><span class="special">;</span>  <span class="comment">// Error, can't convert the result to an mpfr_float_50 as it will lose digits.</span>
67 <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">e</span><span class="special">;</span>  <span class="comment">// Error, operator is ambiguous, result could be of either type.</span>
68 <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">e</span> <span class="special">*</span> <span class="identifier">i</span><span class="special">;</span>  <span class="comment">// OK, unambiguous conversion from mpz_int to static_mpfr_float_50</span>
69 </pre>
70 <h5>
71 <a name="boost_multiprecision.tut.mixed.h1"></a>
72         <span class="phrase"><a name="boost_multiprecision.tut.mixed.operands_of_the_same_precision"></a></span><a class="link" href="mixed.html#boost_multiprecision.tut.mixed.operands_of_the_same_precision">Operands
73         of the Same Precision</a>
74       </h5>
75 <p>
76         Sometimes you want to apply an operator to two arguments of the same precision
77         in such a way as to obtain a result of higher precision. The most common
78         situation occurs with fixed precision integers, where you want to multiply
79         two N-bit numbers to obtain a 2N-bit result. This is supported in this library
80         by the following free functions:
81       </p>
82 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ResultType</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Source1</span> <span class="keyword">class</span> <span class="identifier">Source2</span><span class="special">&gt;</span>
83 <span class="identifier">ResultType</span><span class="special">&amp;</span> <span class="identifier">add</span><span class="special">(</span><span class="identifier">ResultType</span><span class="special">&amp;</span> <span class="identifier">result</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Source1</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Source2</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">);</span>
84
85 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ResultType</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Source1</span> <span class="keyword">class</span> <span class="identifier">Source2</span><span class="special">&gt;</span>
86 <span class="identifier">ResultType</span><span class="special">&amp;</span> <span class="identifier">subtract</span><span class="special">(</span><span class="identifier">ResultType</span><span class="special">&amp;</span> <span class="identifier">result</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Source1</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Source2</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">);</span>
87
88 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ResultType</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Source1</span> <span class="keyword">class</span> <span class="identifier">Source2</span><span class="special">&gt;</span>
89 <span class="identifier">ResultType</span><span class="special">&amp;</span> <span class="identifier">multiply</span><span class="special">(</span><span class="identifier">ResultType</span><span class="special">&amp;</span> <span class="identifier">result</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Source1</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Source2</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">);</span>
90 </pre>
91 <p>
92         These functions apply the named operator to the arguments <span class="emphasis"><em>a</em></span>
93         and <span class="emphasis"><em>b</em></span> and store the result in <span class="emphasis"><em>result</em></span>,
94         returning <span class="emphasis"><em>result</em></span>. In all cases they behave "as
95         if" arguments <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> were
96         first promoted to type <code class="computeroutput"><span class="identifier">ResultType</span></code>
97         before applying the operator, though particular backends may well avoid that
98         step by way of an optimization.
99       </p>
100 <p>
101         The type <code class="computeroutput"><span class="identifier">ResultType</span></code> must
102         be an instance of class <code class="computeroutput"><span class="identifier">number</span></code>,
103         and the types <code class="computeroutput"><span class="identifier">Source1</span></code> and
104         <code class="computeroutput"><span class="identifier">Source2</span></code> may be either instances
105         of class <code class="computeroutput"><span class="identifier">number</span></code> or native
106         integer types. The latter is an optimization that allows arithmetic to be
107         performed on native integer types producing an extended precision result.
108       </p>
109 <p>
110         For example:
111       </p>
112 <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>
113
114 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
115 <span class="special">{</span>
116    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">;</span>
117
118    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uint64_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">uint64_t</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">)();</span>
119    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uint64_t</span> <span class="identifier">j</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
120
121    <span class="identifier">uint128_t</span> <span class="identifier">ui128</span><span class="special">;</span>
122    <span class="identifier">uint256_t</span> <span class="identifier">ui256</span><span class="special">;</span>
123    <span class="comment">//</span>
124    <span class="comment">// Start by performing arithmetic on 64-bit integers to yield 128-bit results:</span>
125    <span class="comment">//</span>
126    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showbase</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
127    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showbase</span> <span class="special">&lt;&lt;</span> <span class="identifier">add</span><span class="special">(</span><span class="identifier">ui128</span><span class="special">,</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">j</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
128    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showbase</span> <span class="special">&lt;&lt;</span> <span class="identifier">multiply</span><span class="special">(</span><span class="identifier">ui128</span><span class="special">,</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
129    <span class="comment">//</span>
130    <span class="comment">// The try squaring a 128-bit integer to yield a 256-bit result:</span>
131    <span class="comment">//</span>
132    <span class="identifier">ui128</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">uint128_t</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">)();</span>
133    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showbase</span> <span class="special">&lt;&lt;</span> <span class="identifier">multiply</span><span class="special">(</span><span class="identifier">ui256</span><span class="special">,</span> <span class="identifier">ui128</span><span class="special">,</span> <span class="identifier">ui128</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
134
135    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
136 <span class="special">}</span>
137 </pre>
138 <p>
139         Produces the output:
140       </p>
141 <pre class="programlisting"><span class="number">0</span><span class="identifier">xffffffffffffffff</span>
142 <span class="number">0</span><span class="identifier">x10000000000000000</span>
143 <span class="number">0</span><span class="identifier">xFFFFFFFFFFFFFFFE0000000000000001</span>
144 <span class="number">0</span><span class="identifier">xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000000000000000000000001</span>
145 </pre>
146 <h5>
147 <a name="boost_multiprecision.tut.mixed.h2"></a>
148         <span class="phrase"><a name="boost_multiprecision.tut.mixed.backends_with_optimized_mixed_pr"></a></span><a class="link" href="mixed.html#boost_multiprecision.tut.mixed.backends_with_optimized_mixed_pr">Backends
149         With Optimized Mixed Precision Arithmetic</a>
150       </h5>
151 <p>
152         The following backends have at least some direct support for mixed precision
153         arithmetic, and therefore avoid creating unnecessary temporaries when using
154         the interfaces above. Therefore when using these types it's more efficient
155         to use mixed precision arithmetic, than it is to explicitly cast the operands
156         to the result type:
157       </p>
158 <p>
159         <a class="link" href="floats/mpfr_float.html" title="mpfr_float">mpfr_float</a>,
160         <a class="link" href="floats/gmp_float.html" title="gmp_float">gmp_float</a>,
161         <a class="link" href="ints/cpp_int.html" title="cpp_int">cpp_int</a>.
162       </p>
163 </div>
164 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
165 <td align="left"></td>
166 <td align="right"><div class="copyright-footer">Copyright &#169; 2002-2019 John Maddock
167       and Christopher Kormanyos<p>
168         Distributed under the Boost Software License, Version 1.0. (See accompanying
169         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>)
170       </p>
171 </div></td>
172 </tr></table>
173 <hr>
174 <div class="spirit-nav">
175 <a accesskey="p" href="rounding.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tut.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="gen_int.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
176 </div>
177 </body>
178 </html>