1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>std::numeric_limits<> constants</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="../limits.html" title="Numeric Limits"> 9<link rel="prev" href="../limits.html" title="Numeric Limits"> 10<link rel="next" href="functions.html" title="std::numeric_limits<> functions"> 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="../limits.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../limits.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="functions.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h4 class="title"> 27<a name="boost_multiprecision.tut.limits.constants"></a><a class="link" href="constants.html" title="std::numeric_limits<> constants">std::numeric_limits<> 28 constants</a> 29</h4></div></div></div> 30<h5> 31<a name="boost_multiprecision.tut.limits.constants.h0"></a> 32 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.is_specialized"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.is_specialized">is_specialized</a> 33 </h5> 34<p> 35 <code class="computeroutput"><span class="keyword">true</span></code> for all arithmetic types 36 (integer, floating and fixed-point) for which <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">numeric_limits</span></code> 37 is specialized. 38 </p> 39<p> 40 A typical test is 41 </p> 42<pre class="programlisting"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_specialized</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">)</span> 43<span class="special">{</span> 44 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"type "</span> <span class="special"><<</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">T</span><span class="special">).</span><span class="identifier">name</span><span class="special">()</span> <span class="special"><<</span> <span class="string">" is not specialized for std::numeric_limits!"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 45<span class="comment">// ...</span> 46<span class="special">}</span> 47</pre> 48<p> 49 Typically <code class="computeroutput"><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_specialized</span></code> 50 is <code class="computeroutput"><span class="keyword">true</span></code> for all <code class="computeroutput"><span class="identifier">T</span></code> where the compile-time constant members 51 of <code class="computeroutput"><span class="identifier">numeric_limits</span></code> are indeed 52 known at compile time, and don't vary at runtime. For example floating-point 53 types with runtime-variable precision such as <code class="computeroutput"><span class="identifier">mpfr_float</span></code> 54 have no <code class="computeroutput"><span class="identifier">numeric_limits</span></code> 55 specialization as it would be impossible to define all the members at compile 56 time. In contrast the precision of a type such as <code class="computeroutput"><span class="identifier">mpfr_float_50</span></code> 57 is known at compile time, and so it <span class="emphasis"><em>does</em></span> have a <code class="computeroutput"><span class="identifier">numeric_limits</span></code> specialization. 58 </p> 59<p> 60 Note that not all the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span></code> 61 member constants and functions are meaningful for all user-defined types 62 (UDT), such as the decimal and binary multiprecision types provided here. 63 More information on this is given in the sections below. 64 </p> 65<h5> 66<a name="boost_multiprecision.tut.limits.constants.h1"></a> 67 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.infinity"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.infinity">infinity</a> 68 </h5> 69<p> 70 For floating-point types, ∞ is defined wherever possible, but clearly infinity 71 is meaningless for __arbitrary_precision arithmetic backends, and there 72 is one floating-point type (GMP's <code class="computeroutput"><span class="identifier">mpf_t</span></code>, 73 see <a class="link" href="../floats/gmp_float.html" title="gmp_float">gmp_float</a>) 74 which has no notion of infinity or NaN at all. 75 </p> 76<p> 77 A typical test whether infinity is implemented is 78 </p> 79<pre class="programlisting"><span class="keyword">if</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">has_infinity</span><span class="special">)</span> 80<span class="special">{</span> 81 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">infinity</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 82<span class="special">}</span> 83</pre> 84<p> 85 and using tests like this is strongly recommended to improve portability. 86 </p> 87<div class="warning"><table border="0" summary="Warning"> 88<tr> 89<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../../doc/src/images/warning.png"></td> 90<th align="left">Warning</th> 91</tr> 92<tr><td align="left" valign="top"><p> 93 If the backend is switched to a type that does not support infinity (or 94 similarly NaNs) then, without checks like this, there will be trouble. 95 </p></td></tr> 96</table></div> 97<h5> 98<a name="boost_multiprecision.tut.limits.constants.h2"></a> 99 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.is_signed"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.is_signed">is_signed</a> 100 </h5> 101<p> 102 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_signed</span> <span class="special">==</span> 103 <span class="keyword">true</span></code> if the type <code class="computeroutput"><span class="identifier">T</span></code> 104 is signed. 105 </p> 106<p> 107 For <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental 108 (built-in)</a> binary types, the sign is held in a single bit, but 109 for other types (<code class="computeroutput"><span class="identifier">cpp_dec_float</span></code> 110 and <code class="computeroutput"><span class="identifier">cpp_bin_float</span></code>) it may 111 be a separate storage element, usually <code class="computeroutput"><span class="keyword">bool</span></code>. 112 </p> 113<h5> 114<a name="boost_multiprecision.tut.limits.constants.h3"></a> 115 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.is_exact"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.is_exact">is_exact</a> 116 </h5> 117<p> 118 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_exact</span> <span class="special">==</span> 119 <span class="keyword">true</span></code> if type T uses exact representations. 120 </p> 121<p> 122 This is defined as <code class="computeroutput"><span class="keyword">true</span></code> for 123 all integer types and <code class="computeroutput"><span class="keyword">false</span></code> 124 for floating-point types. 125 </p> 126<p> 127 <a href="http://stackoverflow.com/questions/14203654/stdnumeric-limitsis-exact-what-is-a-usable-definition" target="_top">A 128 usable definition</a> has been discussed. 129 </p> 130<p> 131 ISO/IEC 10967-1, Language independent arithmetic, noted by the C++ Standard 132 defines 133 </p> 134<pre class="programlisting"><span class="identifier">A</span> <span class="identifier">floating</span><span class="special">-</span><span class="identifier">point</span> <span class="identifier">type</span> <span class="identifier">F</span> <span class="identifier">shall</span> <span class="identifier">be</span> <span class="identifier">a</span> <span class="identifier">finite</span> <span class="identifier">subset</span> <span class="identifier">of</span> <span class="special">[</span><span class="identifier">real</span><span class="special">].</span> 135</pre> 136<p> 137 The important practical distinction is that all integers (up to <code class="computeroutput"><span class="identifier">max</span><span class="special">()</span></code>) 138 can be stored exactly. 139 </p> 140<p> 141 <a href="http://en.wikipedia.org/wiki/Rational_number" target="_top">Rational</a> 142 types using two integer types are also exact. 143 </p> 144<p> 145 Floating-point types <span class="bold"><strong>cannot store all real values</strong></span> 146 (those in the set of ℜ) <span class="bold"><strong>exactly</strong></span>. For example, 147 0.5 can be stored exactly in a binary floating-point, but 0.1 cannot. What 148 is stored is the nearest representable real value, that is, rounded to 149 nearest. 150 </p> 151<p> 152 Fixed-point types (usually decimal) are also defined as exact, in that 153 they only store a <span class="bold"><strong>fixed precision</strong></span>, so 154 half cents or pennies (or less) cannot be stored. The results of computations 155 are rounded up or down, just like the result of integer division stored 156 as an integer result. 157 </p> 158<p> 159 There are number of proposals to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3407.html" target="_top">add 160 Decimal floating-point Support to C++</a>. 161 </p> 162<p> 163 <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2849.pdf" target="_top">Decimal 164 TR</a>. 165 </p> 166<p> 167 And also <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3352.html" target="_top">C++ 168 Binary Fixed-Point Arithmetic</a>. 169 </p> 170<h5> 171<a name="boost_multiprecision.tut.limits.constants.h4"></a> 172 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.is_bounded"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.is_bounded">is_bounded</a> 173 </h5> 174<p> 175 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_bounded</span> <span class="special">==</span> 176 <span class="keyword">true</span></code> if the set of values represented 177 by the type <code class="computeroutput"><span class="identifier">T</span></code> is finite. 178 </p> 179<p> 180 This is <code class="computeroutput"><span class="keyword">true</span></code> for all <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental (built-in) 181 type</a> integer, fixed and floating-point types, and most multi-precision 182 types. 183 </p> 184<p> 185 It is only <code class="computeroutput"><span class="keyword">false</span></code> for a few 186 __arbitrary_precision types like <code class="computeroutput"><span class="identifier">cpp_int</span></code>. 187 </p> 188<p> 189 Rational and fixed-exponent representations are exact but not integer. 190 </p> 191<h5> 192<a name="boost_multiprecision.tut.limits.constants.h5"></a> 193 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.is_modulo"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.is_modulo">is_modulo</a> 194 </h5> 195<p> 196 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_modulo</span></code> is defined as <code class="computeroutput"><span class="keyword">true</span></code> if adding two positive values of type 197 T can yield a result less than either value. 198 </p> 199<p> 200 <code class="computeroutput"><span class="identifier">is_modulo</span> <span class="special">==</span> 201 <span class="keyword">true</span></code> means that the type does not 202 overflow, but, for example, 'wraps around' to zero, when adding one to 203 the <code class="computeroutput"><span class="identifier">max</span><span class="special">()</span></code> 204 value. 205 </p> 206<p> 207 For most <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental 208 (built-in)</a> integer types, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><>::</span><span class="identifier">is_modulo</span></code> 209 is <code class="computeroutput"><span class="keyword">true</span></code>. 210 </p> 211<p> 212 <code class="computeroutput"><span class="keyword">bool</span></code> is the only exception. 213 </p> 214<p> 215 The modulo behaviour is sometimes useful, but also can be unexpected, and 216 sometimes undesired, behaviour. 217 </p> 218<p> 219 Overflow of signed integers can be especially unexpected, possibly causing 220 change of sign. 221 </p> 222<p> 223 Boost.Multiprecision integer type <code class="computeroutput"><span class="identifier">cpp_int</span></code> 224 is not modulo because as an __arbitrary_precision types, it expands to 225 hold any value that the machine resources permit. 226 </p> 227<p> 228 However fixed precision <a class="link" href="../ints/cpp_int.html" title="cpp_int">cpp_int</a>'s 229 may be modulo if they are unchecked (i.e. they behave just like <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental (built-in)</a> 230 integers), but not if they are checked (overflow causes an exception to 231 be raised). 232 </p> 233<p> 234 <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental 235 (built-in)</a> and multi-precision floating-point types are normally 236 not modulo. 237 </p> 238<p> 239 Where possible, overflow is to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><>::</span><span class="identifier">infinity</span><span class="special">()</span></code>, provided <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><>::</span><span class="identifier">has_infinity</span> 240 <span class="special">==</span> <span class="keyword">true</span></code>. 241 </p> 242<h5> 243<a name="boost_multiprecision.tut.limits.constants.h6"></a> 244 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.radix"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.radix">radix</a> 245 </h5> 246<p> 247 Constant <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">radix</span></code> returns either 2 (for <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental 248 (built-in)</a> and binary types) or 10 (for decimal types). 249 </p> 250<h5> 251<a name="boost_multiprecision.tut.limits.constants.h7"></a> 252 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.digits"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.digits">digits</a> 253 </h5> 254<p> 255 The number of <code class="computeroutput"><span class="identifier">radix</span></code> digits 256 that be represented without change: 257 </p> 258<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 259<li class="listitem"> 260 for integer types, the number of <span class="bold"><strong>non-sign bits</strong></span> 261 in the significand. 262 </li> 263<li class="listitem"> 264 for floating types, the number of <span class="bold"><strong>radix digits</strong></span> 265 in the significand. 266 </li> 267</ul></div> 268<p> 269 The values include any implicit bit, so for example, for the ubiquious 270 <code class="computeroutput"><span class="keyword">double</span></code> using 64 bits (<a href="http://en.wikipedia.org/wiki/Double_precision_floating-point_format" target="_top">IEEE 271 binary64 </a>), <code class="computeroutput"><span class="identifier">digits</span></code> 272 == 53, even though there are only 52 actual bits of the significand stored 273 in the representation. The value of <code class="computeroutput"><span class="identifier">digits</span></code> 274 reflects the fact that there is one implicit bit which is always set to 275 1. 276 </p> 277<p> 278 The Boost.Multiprecision binary types do not use an implicit bit, so the 279 <code class="computeroutput"><span class="identifier">digits</span></code> member reflects 280 exactly how many bits of precision were requested: 281 </p> 282<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">number</span><span class="special"><</span><span class="identifier">cpp_bin_float</span><span class="special"><</span><span class="number">53</span><span class="special">,</span> <span class="identifier">digit_base_2</span><span class="special">></span> <span class="special">></span> <span class="identifier">float64</span><span class="special">;</span> 283<span class="keyword">typedef</span> <span class="identifier">number</span><span class="special"><</span><span class="identifier">cpp_bin_float</span><span class="special"><</span><span class="number">113</span><span class="special">,</span> <span class="identifier">digit_base_2</span><span class="special">></span> <span class="special">></span> <span class="identifier">float128</span><span class="special">;</span> 284<span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">float64</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">==</span> <span class="number">53.</span> 285<span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">float128</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">==</span> <span class="number">113.</span> 286</pre> 287<p> 288 For the most common case of <code class="computeroutput"><span class="identifier">radix</span> 289 <span class="special">==</span> <span class="number">2</span></code>, 290 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span></code> is the number of bits in the representation, 291 not counting any sign bit. 292 </p> 293<p> 294 For a decimal integer type, when <code class="computeroutput"><span class="identifier">radix</span> 295 <span class="special">==</span> <span class="number">10</span></code>, 296 it is the number of decimal digits. 297 </p> 298<h5> 299<a name="boost_multiprecision.tut.limits.constants.h8"></a> 300 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.digits10"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.digits10">digits10</a> 301 </h5> 302<p> 303 Constant <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits10</span></code> returns the number of decimal 304 digits that can be represented without change or loss. 305 </p> 306<p> 307 For example, <code class="computeroutput"><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">char</span><span class="special">>::</span><span class="identifier">digits10</span></code> is 2. 308 </p> 309<p> 310 This somewhat inscrutable definition means that an <code class="computeroutput"><span class="keyword">unsigned</span> 311 <span class="keyword">char</span></code> can hold decimal values <code class="computeroutput"><span class="number">0.</span><span class="special">.</span><span class="number">99</span></code> 312 without loss of precision or accuracy, usually from truncation. 313 </p> 314<p> 315 Had the definition been 3 then that would imply it could hold 0..999, but 316 as we all know, an 8-bit <code class="computeroutput"><span class="keyword">unsigned</span> 317 <span class="keyword">char</span></code> can only hold 0..255, and an 318 attempt to store 256 or more will involve loss or change. 319 </p> 320<p> 321 For bounded integers, it is thus <span class="bold"><strong>one less</strong></span> 322 than number of decimal digits you need to display the biggest integer 323 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">max</span><span class="special">()</span></code>. 324 This value can be used to predict the layout width required for 325 </p> 326<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> 327 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">setw</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">short</span><span class="special">>::</span><span class="identifier">digits10</span> <span class="special">+</span><span class="number">1</span> <span class="special">+</span><span class="number">1</span><span class="special">)</span> <span class="comment">// digits10+1, and +1 for sign.</span> 328 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showpos</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"><</span><span class="keyword">short</span><span class="special">>::</span><span class="identifier">max</span><span class="special">)()</span> <span class="comment">// +32767</span> 329 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span> 330 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">setw</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">short</span><span class="special">>::</span><span class="identifier">digits10</span> <span class="special">+</span><span class="number">1</span> <span class="special">+</span><span class="number">1</span><span class="special">)</span> 331 <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"><</span><span class="keyword">short</span><span class="special">>::</span><span class="identifier">min</span><span class="special">)()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// -32767</span> 332</pre> 333<p> 334 For example, <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">short</span></code> 335 is often stored in 16 bits, so the maximum value is 0xFFFF or 65535. 336 </p> 337<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> 338 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">setw</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">short</span><span class="special">>::</span><span class="identifier">digits10</span> <span class="special">+</span><span class="number">1</span> <span class="special">+</span><span class="number">1</span><span class="special">)</span> <span class="comment">// digits10+1, and +1 for sign.</span> 339 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showpos</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"><</span><span class="keyword">unsigned</span> <span class="keyword">short</span><span class="special">>::</span><span class="identifier">max</span><span class="special">)()</span> <span class="comment">// 65535</span> 340 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span> 341 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">setw</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">short</span><span class="special">>::</span><span class="identifier">digits10</span> <span class="special">+</span><span class="number">1</span> <span class="special">+</span><span class="number">1</span><span class="special">)</span> <span class="comment">// digits10+1, and +1 for sign.</span> 342 <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"><</span><span class="keyword">unsigned</span> <span class="keyword">short</span><span class="special">>::</span><span class="identifier">min</span><span class="special">)()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// 0</span> 343</pre> 344<p> 345 For bounded floating-point types, if we create a <code class="computeroutput"><span class="keyword">double</span></code> 346 with a value with <code class="computeroutput"><span class="identifier">digits10</span></code> 347 (usually 15) decimal digits, <code class="computeroutput"><span class="number">1e15</span></code> 348 or <code class="computeroutput"><span class="number">1000000000000000</span></code> : 349 </p> 350<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">max_digits10</span><span class="special">);</span> 351<span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1e15</span><span class="special">;</span> 352<span class="keyword">double</span> <span class="identifier">dp1</span> <span class="special">=</span> <span class="identifier">d</span><span class="special">+</span><span class="number">1</span><span class="special">;</span> 353<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">d</span> <span class="special"><<</span> <span class="string">"\n"</span> <span class="special"><<</span> <span class="identifier">dp1</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 354<span class="comment">// 1000000000000000</span> 355<span class="comment">// 1000000000000001</span> 356<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">dp1</span> <span class="special">-</span> <span class="identifier">d</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// 1</span> 357</pre> 358<p> 359 and we can increment this value to <code class="computeroutput"><span class="number">1000000000000001</span></code> 360 as expected and show the difference too. 361 </p> 362<p> 363 But if we try to repeat this with more than <code class="computeroutput"><span class="identifier">digits10</span></code> 364 digits, 365 </p> 366<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">max_digits10</span><span class="special">);</span> 367<span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1e16</span><span class="special">;</span> 368<span class="keyword">double</span> <span class="identifier">dp1</span> <span class="special">=</span> <span class="identifier">d</span><span class="special">+</span><span class="number">1</span><span class="special">;</span> 369<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">d</span> <span class="special"><<</span> <span class="string">"\n"</span> <span class="special"><<</span> <span class="identifier">dp1</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 370<span class="comment">// 10000000000000000</span> 371<span class="comment">// 10000000000000000</span> 372 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">dp1</span> <span class="special">-</span> <span class="identifier">d</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// 0 !!!</span> 373</pre> 374<p> 375 then we find that when we add one it has no effect, and display show that 376 there is loss of precision. See <a href="http://en.wikipedia.org/wiki/Loss_of_significance" target="_top">Loss 377 of significance or cancellation error</a>. 378 </p> 379<p> 380 So <code class="computeroutput"><span class="identifier">digits10</span></code> is the number 381 of decimal digits <span class="bold"><strong>guaranteed</strong></span> to be correct. 382 </p> 383<p> 384 For example, 'round-tripping' for <code class="computeroutput"><span class="keyword">double</span></code>: 385 </p> 386<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 387<li class="listitem"> 388 If a decimal string with at most <code class="computeroutput"><span class="identifier">digits10</span></code>( 389 == 15) significant decimal digits is converted to <code class="computeroutput"><span class="keyword">double</span></code> 390 and then converted back to the same number of significant decimal digits, 391 then the final string will match the original 15 decimal digit string. 392 </li> 393<li class="listitem"> 394 If a <code class="computeroutput"><span class="keyword">double</span></code> floating-point 395 number is converted to a decimal string with at least 17 decimal digits 396 and then converted back to <code class="computeroutput"><span class="keyword">double</span></code>, 397 then the result will be binary identical to the original <code class="computeroutput"><span class="keyword">double</span></code> value. 398 </li> 399</ul></div> 400<p> 401 For most purposes, you will much more likely want <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><>::</span><span class="identifier">max_digits10</span></code>, 402 the number of decimal digits that ensure that a change of one least significant 403 bit (<a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place" target="_top">Unit 404 in the last place (ULP)</a>) produces a different decimal digits string. 405 </p> 406<p> 407 For the most common <code class="computeroutput"><span class="keyword">double</span></code> 408 floating-point type,<code class="computeroutput"><span class="identifier">max_digits10</span></code> 409 is <code class="computeroutput"><span class="identifier">digits10</span><span class="special">+</span><span class="number">2</span></code>, but you should use C++11 <code class="computeroutput"><span class="identifier">max_digits10</span></code> where possible (see <a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.max_digits10">below</a>). 410 </p> 411<h5> 412<a name="boost_multiprecision.tut.limits.constants.h9"></a> 413 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.max_digits10"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.max_digits10">max_digits10</a> 414 </h5> 415<p> 416 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">max_digits10</span></code> was added for floating-point 417 because <code class="computeroutput"><span class="identifier">digits10</span></code> decimal 418 digits are insufficient to show a least significant bit (ULP) change giving 419 puzzling displays like 420 </p> 421<pre class="programlisting"><span class="number">0.666666666666667</span> <span class="special">!=</span> <span class="number">0.666666666666667</span> 422</pre> 423<p> 424 from failure to 'round-trip', for example: 425 </p> 426<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">write</span> <span class="special">=</span> <span class="number">2.</span><span class="special">/</span><span class="number">3</span><span class="special">;</span> <span class="comment">// Any arbitrary value that cannot be represented exactly.</span> 427<span class="keyword">double</span> <span class="identifier">read</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 428<span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span> <span class="identifier">s</span><span class="special">;</span> 429<span class="identifier">s</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">digits10</span><span class="special">);</span> <span class="comment">// or `float64_t` for 64-bit IEE754 double.</span> 430<span class="identifier">s</span> <span class="special"><<</span> <span class="identifier">write</span><span class="special">;</span> 431<span class="identifier">s</span> <span class="special">>></span> <span class="identifier">read</span><span class="special">;</span> 432<span class="keyword">if</span><span class="special">(</span><span class="identifier">read</span> <span class="special">!=</span> <span class="identifier">write</span><span class="special">)</span> 433<span class="special">{</span> 434 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">digits10</span><span class="special">)</span> 435 <span class="special"><<</span> <span class="identifier">read</span> <span class="special"><<</span> <span class="string">" != "</span> <span class="special"><<</span> <span class="identifier">write</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 436<span class="special">}</span> 437</pre> 438<p> 439 If you wish to ensure that a change of one least significant bit (ULP) 440 produces a different decimal digits string, then <code class="computeroutput"><span class="identifier">max_digits10</span></code> 441 is the precision to use. 442 </p> 443<p> 444 For example: 445 </p> 446<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">pi</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">double_constants</span><span class="special">::</span><span class="identifier">pi</span><span class="special">;</span> 447<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">max_digits10</span><span class="special">);</span> 448<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">pi</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// 3.1415926535897931</span> 449</pre> 450<p> 451 will display π to the maximum possible precision using a <code class="computeroutput"><span class="keyword">double</span></code>. 452 </p> 453<p> 454 and similarly for a much higher precision type: 455 </p> 456<pre class="programlisting"><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> 457 458<span class="keyword">typedef</span> <span class="identifier">number</span><span class="special"><</span><span class="identifier">cpp_dec_float</span><span class="special"><</span><span class="number">50</span><span class="special">></span> <span class="special">></span> <span class="identifier">cpp_dec_float_50</span><span class="special">;</span> <span class="comment">// 50 decimal digits.</span> 459 460<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_dec_float_50</span><span class="special">;</span> 461 462<span class="identifier">cpp_dec_float_50</span> <span class="identifier">pi</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">constants</span><span class="special">::</span><span class="identifier">pi</span><span class="special"><</span><span class="identifier">cpp_dec_float_50</span><span class="special">>();</span> 463<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">cpp_dec_float_50</span><span class="special">>::</span><span class="identifier">max_digits10</span><span class="special">);</span> 464<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">pi</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 465<span class="comment">// 3.141592653589793238462643383279502884197169399375105820974944592307816406</span> 466</pre> 467<p> 468 For integer types, <code class="computeroutput"><span class="identifier">max_digits10</span></code> 469 is implementation-dependent, but is usually <code class="computeroutput"><span class="identifier">digits10</span> 470 <span class="special">+</span> <span class="number">2</span></code>. 471 This is the output field-width required for the maximum value of the type 472 T <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">max</span><span class="special">()</span></code> 473 <span class="emphasis"><em>including a sign and a space</em></span>. 474 </p> 475<p> 476 So this will produce neat columns. 477 </p> 478<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">setw</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">max_digits10</span><span class="special">)</span> <span class="special">...</span> 479</pre> 480<p> 481 The extra two or three least-significant digits are 'noisy' and may be 482 junk, but if you want to 'round-trip' - printing a value out as a decimal 483 digit string and reading it back in - (most commonly during serialization 484 and de-serialization) you must use <code class="computeroutput"><span class="identifier">os</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">max_digits10</span><span class="special">)</span></code>. 485 </p> 486<div class="note"><table border="0" summary="Note"> 487<tr> 488<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td> 489<th align="left">Note</th> 490</tr> 491<tr><td align="left" valign="top"><p> 492 For Microsoft Visual Studio 2010, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">max_digits10</span></code> 493 is wrongly defined as 8. It should be 9. 494 </p></td></tr> 495</table></div> 496<div class="note"><table border="0" summary="Note"> 497<tr> 498<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td> 499<th align="left">Note</th> 500</tr> 501<tr><td align="left" valign="top"> 502<p> 503 For Microsoft Visual Studio before 2013 and the default floating-point 504 format, a small range of double-precision floating-point values with 505 a significand of approximately 0.0001 to 0.004 and exponent values of 506 1010 to 1014 do not round-trip exactly being off by one least significant 507 bit, for probably every third value of the significand. 508 </p> 509<p> 510 A workaround is using the scientific or exponential format <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">scientific</span></code>. 511 </p> 512<p> 513 Other older compilers also fail to implement round-tripping entirely 514 fault-free, for example, see <a href="https://www.exploringbinary.com/incorrectly-rounded-conversions-in-gcc-and-glibc/" target="_top">Incorrectly 515 Rounded Conversions in GCC and GLIBC</a>. 516 </p> 517<p> 518 For more details see <a href="https://www.exploringbinary.com/incorrect-round-trip-conversions-in-visual-c-plus-plus/" target="_top">Incorrect 519 Round-Trip Conversions in Visual C++</a>, and references therein 520 and <a href="https://arxiv.org/pdf/1310.8121.pdf" target="_top">Easy Accurate Reading 521 and Writing of Floating-Point Numbers, Aubrey Jaffer (August 2018)</a>. 522 </p> 523<p> 524 Microsoft VS2017 and other recent compilers, now use the <a href="https://doi.org/10.1145/3192366.3192369" target="_top">Ryu 525 fast float-to-string conversion by Ulf Adams</a> algorithm, claimed 526 to be both exact and fast for 32 and 64-bit floating-point numbers. 527 </p> 528</td></tr> 529</table></div> 530<div class="note"><table border="0" summary="Note"> 531<tr> 532<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td> 533<th align="left">Note</th> 534</tr> 535<tr><td align="left" valign="top"><p> 536 BOOST_NO_CXX11_NUMERIC_LIMITS is a suitable feature-test macro to determine 537 if <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">max_digits10</span></code> is implemented on any 538 platform. 539 </p></td></tr> 540</table></div> 541<div class="note"><table border="0" summary="Note"> 542<tr> 543<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td> 544<th align="left">Note</th> 545</tr> 546<tr><td align="left" valign="top"><p> 547 <span class="emphasis"><em>requires cxx11_numeric_limits</em></span> is a suitable test 548 for use of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">max_digits10</span></code> to control if a target 549 in a jamfile used by a Boost B2/bjam program is built, or not. 550 </p></td></tr> 551</table></div> 552<p> 553 If <code class="computeroutput"><span class="identifier">max_digits10</span></code> is not 554 available, you should use the <a href="http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF" target="_top">Kahan 555 formula for floating-point type T</a>. 556 </p> 557<p> 558 In C++, the equations for what Kahan (on page 4) describes as 'at least' 559 and 'at most' are: 560 </p> 561<pre class="programlisting"><span class="keyword">static</span> <span class="keyword">long</span> <span class="keyword">double</span> <span class="keyword">const</span> <span class="identifier">log10Two</span> <span class="special">=</span> <span class="number">0.30102999566398119521373889472449L</span><span class="special">;</span> <span class="comment">// log10(2.)</span> 562 563<span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">floor</span><span class="special">((</span><span class="identifier">significand_digits</span> <span class="special">-</span> <span class="number">1</span><span class="special">)</span> <span class="special">*</span> <span class="identifier">log10Two</span><span class="special">));</span> <span class="comment">// == digits10 - 'at least' .</span> 564<span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">ceil</span><span class="special">(</span><span class="number">1</span> <span class="special">+</span> <span class="identifier">significand_digits</span> <span class="special">*</span> <span class="identifier">log10Two</span><span class="special">));</span> <span class="comment">// == max_digits10 - 'at most'.</span> 565</pre> 566<p> 567 Unfortunately, these cannot be evaluated (at least by C++03) at <span class="bold"><strong>compile-time</strong></span>. So the following expression is often 568 used instead. 569 </p> 570<pre class="programlisting"><span class="identifier">max_digits10</span> <span class="special">=</span> <span class="number">2</span> <span class="special">+</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">3010U</span><span class="special">/</span><span class="number">10000U</span><span class="special">;</span> 571 572<span class="comment">// == 2 + std::numeric_limits<T>::digits for double and 64-bit long double.</span> 573<span class="comment">// == 3 + std::numeric_limits<T>::digits for float, 80-bit long-double and __float128.</span> 574</pre> 575<p> 576 often the actual values are computed for the C limits macros: 577 </p> 578<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">FLT_MAXDIG10</span> <span class="special">(</span><span class="number">2</span><span class="special">+</span><span class="identifier">FLT_MANT_DIG</span> <span class="special">*</span> <span class="number">3010U</span><span class="special">/</span><span class="number">10000U</span><span class="special">)</span> <span class="comment">// 9</span> 579<span class="preprocessor">#define</span> <span class="identifier">DBL_MAXDIG10</span> <span class="special">(</span><span class="number">2</span><span class="special">+</span> <span class="special">(</span><span class="identifier">DBL_MANT_DIG</span> <span class="special">*</span> <span class="number">3010U</span><span class="special">)/</span><span class="number">10000U</span><span class="special">)</span> <span class="comment">// 17</span> 580<span class="preprocessor">#define</span> <span class="identifier">LDBL_MAXDIG10</span> <span class="special">(</span><span class="number">2</span><span class="special">+</span> <span class="special">(</span><span class="identifier">LDBL_MANT_DIG</span> <span class="special">*</span> <span class="number">3010U</span><span class="special">)/</span><span class="number">10000U</span><span class="special">)</span> <span class="comment">// 17 for MSVC, 18 for others.</span> 581</pre> 582<p> 583 The factor 3010U/10000U is <span class="emphasis"><em>log<sub>10</sub>(2) = 0.3010</em></span> that 584 can be evaluated at compile-time using only <code class="computeroutput"><span class="keyword">short</span> 585 <span class="keyword">unsigned</span> <span class="keyword">int</span></code>s 586 to be a desirable <code class="computeroutput"><span class="keyword">const</span></code> or 587 <code class="computeroutput"><span class="keyword">constexpr</span></code> (and usually also 588 <code class="computeroutput"><span class="keyword">static</span></code>). 589 </p> 590<p> 591 Boost macros allow this to be done portably, see <a href="http://www.boost.org/doc/libs/1_58_0/libs/config/doc/html/boost_config/boost_macro_reference.html" target="_top">BOOST_CONSTEXPR_OR_CONST 592 or BOOST_STATIC_CONSTEXPR</a>. 593 </p> 594<p> 595 (See also <a href="http://www.loria.fr/~zimmerma/mca/mca-cup-0.5.9.pdf" target="_top">Richard 596 P. Brent and Paul Zimmerman, Modern Computer Arithmetic</a> Equation 597 3.8 on page 116). 598 </p> 599<p> 600 For example, to be portable (including obselete platforms) for type <code class="computeroutput"><span class="identifier">T</span></code> where <code class="computeroutput"><span class="identifier">T</span></code> 601 may be: <code class="computeroutput"><span class="keyword">float</span></code>, <code class="computeroutput"><span class="keyword">double</span></code>, <code class="computeroutput"><span class="keyword">long</span> 602 <span class="keyword">double</span></code>, <code class="computeroutput"><span class="number">128</span><span class="special">-</span><span class="identifier">bit</span> <span class="identifier">quad</span> <span class="identifier">type</span></code>, 603 <code class="computeroutput"><span class="identifier">cpp_bin_float_50</span></code> ... 604 </p> 605<pre class="programlisting"> <span class="keyword">typedef</span> <span class="keyword">float</span> <span class="identifier">T</span><span class="special">;</span> 606 607<span class="preprocessor">#if</span> <span class="identifier">defined</span> <span class="identifier">BOOST_NO_CXX11_NUMERIC_LIMITS</span> 608 <span class="comment">// No max_digits10 implemented.</span> 609 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">max_digits10</span><span class="special"><</span><span class="identifier">T</span><span class="special">>());</span> 610<span class="preprocessor">#else</span> 611 <span class="preprocessor">#if</span><span class="special">(</span><span class="identifier">_MSC_VER</span> <span class="special"><=</span> <span class="number">1600</span><span class="special">)</span> 612 <span class="comment">// The MSVC 2010 version had the wrong value for std::numeric_limits<float>::max_digits10.</span> 613 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">max_digits10</span><span class="special"><</span><span class="identifier">T</span><span class="special">>());</span> 614 <span class="preprocessor">#else</span> <span class="comment">// Use the C++11 max_digits10.</span> 615 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">max_digits10</span><span class="special">);</span> 616 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits10</span><span class="special">);</span> 617 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">setf</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">showpoint</span><span class="special">);</span> <span class="comment">// Append any trailing zeros,</span> 618 <span class="comment">// or more memorably</span> 619 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showpoint</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// </span> 620 <span class="preprocessor">#endif</span> 621<span class="preprocessor">#endif</span> 622 623 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"std::cout.precision(max_digits10) = "</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// 9</span> 624 625 <span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">1.2345678901234567889</span><span class="special">;</span> 626 627 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"x = "</span> <span class="special"><<</span> <span class="identifier">x</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">//</span> 628</pre> 629<p> 630 which should output: 631 </p> 632<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">max_digits10</span><span class="special">)</span> <span class="special">=</span> <span class="number">9</span> 633<span class="identifier">x</span> <span class="special">=</span> <span class="number">1.23456789</span> 634</pre> 635<h5> 636<a name="boost_multiprecision.tut.limits.constants.h10"></a> 637 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.round_style"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.round_style">round_style</a> 638 </h5> 639<p> 640 The rounding style determines how the result of floating-point operations 641 is treated when the result cannot be <span class="bold"><strong>exactly represented</strong></span> 642 in the significand. Various rounding modes may be provided: 643 </p> 644<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 645<li class="listitem"> 646 round to nearest up or down (default for floating-point types). 647 </li> 648<li class="listitem"> 649 round up (toward positive infinity). 650 </li> 651<li class="listitem"> 652 round down (toward negative infinity). 653 </li> 654<li class="listitem"> 655 round toward zero (integer types). 656 </li> 657<li class="listitem"> 658 no rounding (if decimal radix). 659 </li> 660<li class="listitem"> 661 rounding mode is not determinable. 662 </li> 663</ul></div> 664<p> 665 For integer types, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">round_style</span></code> 666 is always towards zero, so 667 </p> 668<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">round_style</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">round_to_zero</span><span class="special">;</span> 669</pre> 670<p> 671 A decimal type, <code class="computeroutput"><span class="identifier">cpp_dec_float</span></code> 672 rounds in no particular direction, which is to say it doesn't round at 673 all. And since there are several guard digits, it's not really the same 674 as truncation (round toward zero) either. 675 </p> 676<p> 677 For floating-point types, it is normal to round to nearest. 678 </p> 679<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">round_style</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">round_to_nearest</span><span class="special">;</span> 680</pre> 681<p> 682 See function <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">round_error</span></code> for the maximum error (in 683 ULP) that rounding can cause. 684 </p> 685<h5> 686<a name="boost_multiprecision.tut.limits.constants.h11"></a> 687 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.has_denorm_loss"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.has_denorm_loss">has_denorm_loss</a> 688 </h5> 689<p> 690 <code class="computeroutput"><span class="keyword">true</span></code> if a loss of precision 691 is detected as a <a href="http://en.wikipedia.org/wiki/Denormalization" target="_top">denormalization</a> 692 loss, rather than an inexact result. 693 </p> 694<p> 695 Always <code class="computeroutput"><span class="keyword">false</span></code> for integer types. 696 </p> 697<p> 698 <code class="computeroutput"><span class="keyword">false</span></code> for all types which 699 do not have <code class="computeroutput"><span class="identifier">has_denorm</span></code> 700 == <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">denorm_present</span></code>. 701 </p> 702<h5> 703<a name="boost_multiprecision.tut.limits.constants.h12"></a> 704 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.denorm_style"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.denorm_style">denorm_style</a> 705 </h5> 706<p> 707 <a href="http://en.wikipedia.org/wiki/Denormal_number" target="_top">Denormalized 708 values</a> are representations with a variable number of exponent bits 709 that can permit gradual underflow, so that, if type T is <code class="computeroutput"><span class="keyword">double</span></code>. 710 </p> 711<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">denorm_min</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"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">min</span><span class="special">()</span> 712</pre> 713<p> 714 A type may have any of the following <code class="computeroutput"><span class="keyword">enum</span> 715 <span class="identifier">float_denorm_style</span></code> values: 716 </p> 717<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 718<li class="listitem"> 719 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">denorm_absent</span></code>, if it does not allow 720 denormalized values. (Always used for all integer and exact types). 721 </li> 722<li class="listitem"> 723 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">denorm_present</span></code>, if the floating-point 724 type allows denormalized values. 725 </li> 726<li class="listitem"> 727 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">denorm_indeterminate</span></code>, if indeterminate 728 at compile time. 729 </li> 730</ul></div> 731<h5> 732<a name="boost_multiprecision.tut.limits.constants.h13"></a> 733 <span class="phrase"><a name="boost_multiprecision.tut.limits.constants.tinyness_before_rounding"></a></span><a class="link" href="constants.html#boost_multiprecision.tut.limits.constants.tinyness_before_rounding">Tinyness 734 before rounding</a> 735 </h5> 736<p> 737 <code class="computeroutput"><span class="keyword">bool</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">tinyness_before</span></code> 738 </p> 739<p> 740 <code class="computeroutput"><span class="keyword">true</span></code> if a type can determine 741 that a value is too small to be represent as a normalized value before 742 rounding it. 743 </p> 744<p> 745 Generally true for <code class="computeroutput"><span class="identifier">is_iec559</span></code> 746 floating-point __fundamantal types, but false for integer types. 747 </p> 748<p> 749 Standard-compliant IEEE 754 floating-point implementations may detect the 750 floating-point underflow at three predefined moments: 751 </p> 752<div class="orderedlist"><ol class="orderedlist" type="1"> 753<li class="listitem"> 754 After computation of a result with absolute value smaller than <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">min</span><span class="special">()</span></code>, 755 such implementation detects <span class="emphasis"><em>tinyness before rounding</em></span> 756 (e.g. UltraSparc). 757 </li> 758<li class="listitem"> 759 After rounding of the result to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span></code> 760 bits, if the result is tiny, such implementation detects <span class="emphasis"><em>tinyness 761 after rounding</em></span> (e.g. SuperSparc). 762 </li> 763<li class="listitem"> 764 If the conversion of the rounded tiny result to subnormal form resulted 765 in the loss of precision, such implementation detects <span class="emphasis"><em>denorm 766 loss</em></span>. 767 </li> 768</ol></div> 769</div> 770<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 771<td align="left"></td> 772<td align="right"><div class="copyright-footer">Copyright © 2002-2020 John 773 Maddock and Christopher Kormanyos<p> 774 Distributed under the Boost Software License, Version 1.0. (See accompanying 775 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>) 776 </p> 777</div></td> 778</tr></table> 779<hr> 780<div class="spirit-nav"> 781<a accesskey="p" href="../limits.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../limits.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="functions.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> 782</div> 783</body> 784</html> 785