• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Constructing and Interconverting Between Number Types</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 1. Boost.Multiprecision">
8<link rel="up" href="../tut.html" title="Tutorial">
9<link rel="prev" href="misc/visualizers.html" title="Visual C++ Debugger Visualizers">
10<link rel="next" href="random.html" title="Generating Random Numbers">
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="misc/visualizers.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="random.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.conversions"></a><a class="link" href="conversions.html" title="Constructing and Interconverting Between Number Types">Constructing and
28      Interconverting Between Number Types</a>
29</h3></div></div></div>
30<p>
31        All of the number types that are based on <code class="computeroutput"><span class="identifier">number</span></code>
32        have certain conversion rules in common. In particular:
33      </p>
34<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
35<li class="listitem">
36<p class="simpara">
37            Any number type can be constructed (or assigned) from any <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
38            (built-in)</a> arithmetic type, as long as the conversion isn't lossy
39            (for example float to int conversion):
40          </p>
41<pre class="programlisting"><span class="identifier">cpp_dec_float_50</span> <span class="identifier">df</span><span class="special">(</span><span class="number">0.5</span><span class="special">);</span>   <span class="comment">// OK construction from double</span>
42<span class="identifier">cpp_int</span>          <span class="identifier">i</span><span class="special">(</span><span class="number">450</span><span class="special">);</span>    <span class="comment">// OK constructs from signed int</span>
43<span class="identifier">cpp_int</span>          <span class="identifier">j</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">;</span>  <span class="comment">// Error, lossy conversion.</span>
44</pre>
45</li>
46<li class="listitem">
47<p class="simpara">
48            A number can be explicitly constructed from an arithmetic type, even
49            when the conversion is lossy:
50          </p>
51<pre class="programlisting"><span class="identifier">cpp_int</span>          <span class="identifier">i</span><span class="special">(</span><span class="number">3.14</span><span class="special">);</span>       <span class="comment">// OK explicit conversion</span>
52<span class="identifier">i</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">cpp_int</span><span class="special">&gt;(</span><span class="number">3.14</span><span class="special">)</span>  <span class="comment">// OK explicit conversion</span>
53<span class="identifier">i</span><span class="special">.</span><span class="identifier">assign</span><span class="special">(</span><span class="number">3.14</span><span class="special">);</span>                 <span class="comment">// OK, explicit assign and avoid a temporary from the cast above</span>
54<span class="identifier">i</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">;</span>                       <span class="comment">// Error, no implicit assignment operator for lossy conversion.</span>
55<span class="identifier">cpp_int</span>          <span class="identifier">j</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">;</span>      <span class="comment">// Error, no implicit constructor for lossy conversion.</span>
56</pre>
57</li>
58<li class="listitem">
59<p class="simpara">
60            A <code class="computeroutput"><span class="identifier">number</span></code> can be converted
61            to any <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
62            (built-in)</a> type, via the <code class="computeroutput"><span class="identifier">convert_to</span></code>
63            member function:
64          </p>
65<pre class="programlisting"><span class="identifier">mpz_int</span> <span class="identifier">z</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
66<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">.</span><span class="identifier">convert_to</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;();</span> <span class="comment">// sets i to 2</span>
67</pre>
68</li>
69<li class="listitem">
70            Conversions to rational numbers from floating-point ones are always allowed,
71            and are exact and implicit as long as the rational number uses an unbounded
72            integer type. Please be aware that constructing a rational number from
73            an extended precision floating-point type with a large exponent range
74            can effectively run the system out of memory, as in the extreme case
75            <span class="emphasis"><em>2<sup>max_exponent</sup> / CHAR_BITS</em></span> bytes of storage may be
76            required. This does not represent a problem for <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
77            (built-in)</a> floating-point types however, as the exponent range
78            for these is rather limited.
79          </li>
80<li class="listitem">
81            Conversions to floating-point numbers from rational ones are rounded
82            to nearest (less than 0.5 <a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place" target="_top">Unit
83            in the last place (ULP)</a> error) as long as the floating-point
84            number is binary, and the integer type used by the rational number is
85            unbounded.
86          </li>
87</ul></div>
88<p>
89        Additional conversions may be supported by particular backends.
90      </p>
91<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
92<li class="listitem">
93<p class="simpara">
94            A <code class="computeroutput"><span class="identifier">number</span></code> can be converted
95            to any <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
96            (built-in)</a> type, via an explicit conversion operator: this functionality
97            is only available on compilers supporting C++11's explicit conversion
98            syntax.
99          </p>
100<pre class="programlisting"><span class="identifier">mpz_int</span> <span class="identifier">z</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
101<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>                     <span class="comment">// Error, implicit conversion not allowed.</span>
102<span class="keyword">int</span> <span class="identifier">j</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">z</span><span class="special">);</span>   <span class="comment">// OK explicit conversion.</span>
103</pre>
104</li>
105<li class="listitem">
106<p class="simpara">
107            Any number type can be <span class="emphasis"><em>explicitly</em></span> constructed (or
108            assigned) from a <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span></code>
109            or a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>:
110          </p>
111<pre class="programlisting"><span class="comment">// pi to 50 places from a string:</span>
112<span class="identifier">cpp_dec_float_50</span> <span class="identifier">df</span><span class="special">(</span><span class="string">"3.14159265358979323846264338327950288419716939937510"</span><span class="special">);</span>
113<span class="comment">// Integer type will automatically detect "0x" and "0" prefixes and parse the string accordingly:</span>
114<span class="identifier">cpp_int</span>          <span class="identifier">i</span><span class="special">(</span><span class="string">"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000"</span><span class="special">);</span>
115<span class="comment">// Invalid input always results in a std::runtime_error being thrown:</span>
116<span class="identifier">i</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">cpp_int</span><span class="special">&gt;(</span><span class="string">"3.14"</span><span class="special">);</span>
117<span class="comment">// implicit conversions from strings are not allowed:</span>
118<span class="identifier">i</span> <span class="special">=</span> <span class="string">"23"</span><span class="special">;</span> <span class="comment">// Error, no assignment operator for implicit conversion from string</span>
119<span class="comment">// assign member function, avoids having to create a temporary via a static_cast:</span>
120<span class="identifier">i</span><span class="special">.</span><span class="identifier">assign</span><span class="special">(</span><span class="string">"23"</span><span class="special">);</span>  <span class="comment">// OK</span>
121</pre>
122</li>
123<li class="listitem">
124<p class="simpara">
125            Any number type will interoperate with the <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
126            (built-in)</a> types in arithmetic expressions as long as the conversions
127            are not lossy:
128          </p>
129<pre class="programlisting"><span class="comment">// pi to 50 places from a string:</span>
130<span class="identifier">cpp_dec_float_50</span> <span class="identifier">df</span> <span class="special">=</span> <span class="string">"3.14159265358979323846264338327950288419716939937510"</span><span class="special">;</span>
131<span class="comment">// Multiply by 2 - using an integer literal here is usually more efficient</span>
132<span class="comment">// than constructing a temporary:</span>
133<span class="identifier">df</span> <span class="special">*=</span> <span class="number">2</span><span class="special">;</span>
134
135<span class="comment">// You can't mix integer types with floats though:</span>
136<span class="identifier">cpp_int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span>
137<span class="identifier">i</span> <span class="special">*=</span> <span class="number">3.14</span><span class="special">;</span>  <span class="comment">// Error, no *= operator will be found.</span>
138</pre>
139</li>
140<li class="listitem">
141<p class="simpara">
142            Any number type can be streamed to and from the C++ iostreams:
143          </p>
144<pre class="programlisting"><span class="identifier">cpp_dec_float_50</span> <span class="identifier">df</span> <span class="special">=</span> <span class="string">"3.14159265358979323846264338327950288419716939937510"</span><span class="special">;</span>
145<span class="comment">// Now print at full precision:</span>
146<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">setprecision</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">cpp_dec_float_50</span><span class="special">&gt;::</span><span class="identifier">max_digits10</span><span class="special">)</span>
147   <span class="special">&lt;&lt;</span> <span class="identifier">df</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span>
148<span class="identifier">cpp_int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
149<span class="identifier">i</span> <span class="special">&lt;&lt;=</span> <span class="number">256</span><span class="special">;</span>
150<span class="comment">// Now print in hex format with prefix:</span>
151<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>
152</pre>
153</li>
154<li class="listitem">
155<p class="simpara">
156            Interconversions between number types of the same family are allowed
157            and are implicit conversions if no loss of precision is involved, and
158            explicit if it is:
159          </p>
160<pre class="programlisting"><span class="identifier">int128_t</span>     <span class="identifier">i128</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
161<span class="identifier">int266_t</span>     <span class="identifier">i256</span> <span class="special">=</span> <span class="identifier">i128</span><span class="special">;</span>  <span class="comment">// OK implicit widening conversion</span>
162<span class="identifier">i128_t</span>            <span class="special">=</span> <span class="identifier">i256</span><span class="special">;</span>  <span class="comment">// Error, no assignment operator found, narrowing conversion is explicit.</span>
163<span class="identifier">i128_t</span>            <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">int128_t</span><span class="special">&gt;(</span><span class="identifier">i256</span><span class="special">);</span> <span class="comment">// OK, explicit narrowing conversion.</span>
164
165<span class="identifier">mpz_int</span>      <span class="identifier">z</span>    <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
166<span class="identifier">mpf_float</span>    <span class="identifier">f</span>    <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>    <span class="comment">// OK, GMP handles this conversion natively, and it's not lossy and therefore implicit.</span>
167
168<span class="identifier">mpf_float_50</span> <span class="identifier">f50</span>  <span class="special">=</span> <span class="number">2</span><span class="special">;</span>
169<span class="identifier">f</span>                 <span class="special">=</span> <span class="identifier">f50</span><span class="special">;</span>  <span class="comment">// OK, conversion from fixed to variable precision, f will have 50 digits precision.</span>
170<span class="identifier">f50</span>               <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span>    <span class="comment">// Error, conversion from variable to fixed precision is potentially lossy, explicit cast required.</span>
171</pre>
172</li>
173<li class="listitem">
174<p class="simpara">
175            Some interconversions between number types are completely generic, and
176            are always available, albeit the conversions are always <span class="emphasis"><em>explicit</em></span>:
177          </p>
178<pre class="programlisting"><span class="identifier">cpp_int</span> <span class="identifier">cppi</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
179<span class="comment">// We can always convert between numbers of the same category -</span>
180<span class="comment">// int to int, rational to rational, or float to float, so this is OK</span>
181<span class="comment">// as long as we use an explicit conversion:</span>
182<span class="identifier">mpz_int</span> <span class="identifier">z</span><span class="special">(</span><span class="identifier">cppi</span><span class="special">);</span>
183<span class="comment">// We can always promote from int to rational, int to float, or rational to float:</span>
184<span class="identifier">cpp_rational</span>     <span class="identifier">cppr</span><span class="special">(</span><span class="identifier">cppi</span><span class="special">);</span>  <span class="comment">// OK, int to rational</span>
185<span class="identifier">cpp_dec_float_50</span> <span class="identifier">df</span><span class="special">(</span><span class="identifier">cppi</span><span class="special">);</span>    <span class="comment">// OK, int to float</span>
186<span class="identifier">df</span>                  <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">cpp_dec_float_50</span><span class="special">&gt;(</span><span class="identifier">cppr</span><span class="special">);</span>  <span class="comment">// OK, explicit rational to float conversion</span>
187<span class="comment">// However narrowing and/or implicit conversions always fail:</span>
188<span class="identifier">cppi</span>                <span class="special">=</span>   <span class="identifier">df</span><span class="special">;</span>    <span class="comment">// Compiler error, conversion not allowed</span>
189</pre>
190</li>
191<li class="listitem">
192<p class="simpara">
193            Other interconversions may be allowed as special cases, whenever the
194            backend allows it:
195          </p>
196<pre class="programlisting"><span class="identifier">mpf_t</span>     <span class="identifier">m</span><span class="special">;</span>           <span class="comment">// Native GMP type.</span>
197<span class="identifier">mpf_init_set_ui</span><span class="special">(</span><span class="identifier">m</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// set to a value;</span>
198<span class="identifier">mpf_float</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">m</span><span class="special">);</span>        <span class="comment">// copies the value of the native type.</span>
199</pre>
200</li>
201</ul></div>
202<p>
203        More information on what additional types a backend supports conversions
204        from are given in the tutorial for each backend. The converting constructor
205        will be implicit if the backend's converting constructor is also implicit,
206        and explicit if the backends converting constructor is also explicit.
207      </p>
208</div>
209<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
210<td align="left"></td>
211<td align="right"><div class="copyright-footer">Copyright © 2002-2020 John
212      Maddock and Christopher Kormanyos<p>
213        Distributed under the Boost Software License, Version 1.0. (See accompanying
214        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>)
215      </p>
216</div></td>
217</tr></table>
218<hr>
219<div class="spirit-nav">
220<a accesskey="p" href="misc/visualizers.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="random.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
221</div>
222</body>
223</html>
224